LINQ嵌套选择

时间:2014-04-24 16:03:39

标签: asp.net-mvc linq

我有2 class如下:

public class Outlet
{
    [Key]
    public int outletID { get; set; }

    [Required]
    [StringLength(10, MinimumLength = 2)]
    [Display(Name = "Code")]
    public string outletCode { get; set; }

    [Required]
    [StringLength(100, MinimumLength = 3)]
    [Display(Name = "Name")]
    public string outletName { get; set; }

    [DataType(DataType.Date)]
    [DisplayFormat(DataFormatString = "{0:dd MMM yyyy}", ApplyFormatInEditMode = true)]
    [Display(Name = "Opening Date")]
    public DateTime outletOpeningDate { get; set; }

    [Required]
    public int managerID { get; set; }

    public User manager { get; set; }

    public int supervisorID { get; set; }

    public User supervisor { get; set; }

    [Required]
    [StringLength(200, MinimumLength = 3)]
    [Display(Name = "Address")]
    public string outletAddress { get; set; }

    [StringLength(20, MinimumLength = 1)]
    [Display(Name = "Unit No")]
    public string outletUnitNo { get; set; }

    [Required]
    [StringLength(6, MinimumLength = 6)]
    [Display(Name = "Postal Code")]
    public string outletPostalCode { get; set; }

    [StringLength(10)]
    [Display(Name = "Phone No")]
    public string outletPhoneNo { get; set; }

    public bool deleted { get; set; }
}

public class User
{
    [Key]
    public int userID { get; set; }

    [Required]
    [StringLength(50, MinimumLength = 4)]
    [Display(Name = "Username")]
    public string userName { get; set; }

    [Required]
    [StringLength(100, MinimumLength = 4)]
    [Display(Name = "Name")]
    public string name { get; set; }

    [StringLength(100)]
    [DataType(DataType.EmailAddress)]
    [EmailValidation(ErrorMessage = "Not a valid Email Address.")]
    [Display(Name = "Email")]
    public string email { get; set; }

    [Required]
    [DataType(DataType.Password)]
    [Display(Name = "Password")]
    [StringLength(50, MinimumLength = 6)]
    public string password { get; set; }

    [Required]
    [Display(Name = "Roles")]
    public int rolesID { get; set; }

    public Role roles { get; set; }

    public bool deleted { get; set; }
}

在我的插座课程中,我有这2个用户class实例

public User manager { get; set; }
public User supervisor { get; set; }

我需要获取所有outlet列表,并根据managerID (FK: userid in table user)获取经理详细信息(来自用户表) 并根据supervisorID (FK: userid in table user)

获取主管详细信息(也来自用户表)

我试过这个linq

IEnumerable<Outlet> outlet = (
                    from o in db.Outlets
                    .AsEnumerable()
                    select new Outlet
                    {

                        outletID = o.outletID,
                        outletCode = o.outletCode,
                        outletName = o.outletName,
                        outletOpeningDate = o.outletOpeningDate,
                        managerID = o.managerID,

                        supervisorID = o.supervisorID,
                        outletAddress = o.outletAddress,
                        outletUnitNo = o.outletUnitNo,
                        outletPostalCode = o.outletPostalCode,
                        outletPhoneNo = o.outletPhoneNo,

                        manager = db.Users.Where(u => u.deleted == false).Where(u => u.userID == o.managerID).FirstOrDefault(),

                        supervisor = db.Users.Where(u => u.deleted == false).Where(u => u.userID == o.supervisorID).FirstOrDefault()
                    });

return View(outlet.ToList());

但我收到此错误: Invalid column name 'manager_userID'. Invalid column name 'supervisor_userID'.

如何使用linq与类内的类进行嵌套选择?

抱歉我的英语很差,希望你能明白我的意思..

1 个答案:

答案 0 :(得分:2)

您的代码需要解决更多问题。 您需要确保在编写LINQ查询之前可以在SQL中执行此操作。

基本上下面的代码应该可以解决问题(遗憾的是我现在无法测试它。)。

注意:仅仅因为存在4个查询并不意味着您的应用和数据库之间将会有4个执行查询。 Note2 :只是因为只有一个查询在您的应用和数据库之间执行,并不意味着数据库不必通过索引进行3次单独传递。

var query1 = from user in db.Users
             join outlet in db.Outlets
             on user equals outlet.manager
             select new { outlet, user };
var query2 = from user in db.Users
             join outlet in db.Outlets
             on user equals outlet.supervisor
             select new { outlet, user };
var query3 = from outlet in db.Outlets
             where (outlet.manager == null) && (outlet.supervisor == null)
             select new { outlet = outlet, user = null as User };
var unionQuery = query1.Concat(query2).Concat(query3);

List<Outlet> all = unionQuery
   .AsEnumerable()
   .Select(obj => obj.outlet)
   .Distinct()
   .ToList();

return View(all);

我们在这些查询中明确请求managersupervisor关系属性的简单事实是指示我们需要提前加载ORM的ORM。

祝你好运:)