2016-07-07 145 views
2

好日子,C#LINQ查询过滤器子集合

我有一个像下面

public class EmployeeModel 
    { 
     [Key] 
    public int employeeId{get;set;} 
    public string Fullname {get;set;} 
    public string Address{get;set;} 
    public ICollection<PaymentModel> Payments {get;set;} 
    } 


    public class PaymentModel 
    { 

     [Key] 
    public int PaymentId{get; set;} 
    public int employeeId{get; set;} 
    public decimal PaymentAmount{get; set;} 
     public int IsPosted {get; set;} 
     public virtual EmployeeModel Employee {get; set;} 

    } 

我只是想与他们使用LINQ付款列表一起查询员工列表中选择一个模型类。所以我这样的代码:

dbcontext db = new dbcontext(); 
var listing = from d in db.Employees 
       .include("Payments") 
       select d; 

此列表显示所有员工及其所有付款。 但我需要过滤每个员工付款,IsPosted = 1

所以最初的答案,虐待这样的代码;

dbcontext db = new dbcontext(); 
List<EmployeeModel> FinalList = new List<EmployeeModel>(); 
var listingofEmp = db.employee.ToList(); 

foreach(EmployeeModel emp in listingofEmp){ 
emp.Payments= db.payments.where(x => x.IsPosted == 1).ToList(); 
FinalList.Add(emp); 
} 

我的问题是,是否有任何其他方式来更容易编码?像这样的东西。

dbcontext db = new dbcontext(); 
    var listing = from d in db.Employees 
        .include(d => x.Payments.IsPosted == 1) 
        select d; 

IM curently使用的EntityFramework 5

香港专业教育学院的研究把它不为我工作Link

希望有人能帮助我

在此先感谢家伙

回答

3

什么是你要求的是其本身不支持,所以没有更简单的方法,但是可以肯定有更有效的方式,因为你当前的代码正在执行N + 1次的数据库查询。

更好的方法是使用匿名类型投影检索一个数据库查询员工和相关的过滤支付,然后执行类似于您的方法的内容以在内存中创建最终结果。例如:

var listing = 
    db.Employees.Select(employee => new 
    { 
     employee, 
     payments = employee.Payments.Where(p => p.IsPosted == 1) 
    }) 
    .AsEnumerable() // Switch to LINQ to Objects 
    .Select(r => 
    { 
     r.employee.Payments = r.payments.ToList(); 
     return r.employee; 
    }) 
    .ToList(); 
+0

它的工作原理就像一个魅力.. !!!谢谢你帮助先生伊万..先生伊万我可以问我在哪里可以了解更多linq?任何链接或书籍?希望听到你的先生请;(... – Neil

+0

嗨尼尔,我真的不知道该怎么建议你。林肯定LINQ有很多优秀的书籍/链接,但我个人从MSDN主题学到了一切,主要是尝试。请注意,不同的LINQ实现具有特定的细节,因此上面的例子可能适用于或不适用于最新的EF Core。 –

+0

有没有在ef6中使用linq做同样的方法?我在ef6中尝试了相同的逻辑,但它没有过滤子集合。 – overloading

1

它colud是不错的替代品

var listing = from d in db.Payments 
       .include("Employees") 
       .where d.IsPosted == 1 
       select d.Employees; 

(未测试,那么请修正错误)的张贴= 1

从pyaments开始,过滤器,然后选择相关的就业者

+0

感谢眼前的answere @Danilo Calzetta ..我会尝试用这样的:d – Neil

+0

喜先生@Danilo Calzetta,有另一种方式?我需要绑定Employee的列表,然后是其付款的子报表..这种方式将更加困难,因为我需要循环每个支付组到一个列表..所以我可以将其绑定到我的WPF UI的列表视图。 。 – Neil

+0

@Neil请看看我的示例查询,它完全返回一个列表员工,因为选择“d.emplyees”而不是“d” –

0

尝试是这样的:它会给你的匿名列表类型,将持有员工和它的付款。

using (dbcontext ctx = new dbcontext()) 
{ 
    ctx.Connection.Open(); 

    var result = (from e in ctx.Employees 
        join p in ctx.Payments on e.employeeId equals p.employeeId 
        where p.IsPosted == 1 
        select new 
        { 
         Employee = e, 
         Payments = p 
        }).ToList(); 

    ctx.Connection.Close(); 
} 
+0

嗨@Paul我会试试这个..感谢您的评论 – Neil

+0

hi @Paul how我可以使用结果吗?我想将它封装到员工列表中,这样我就可以将它绑定到我的WPF UI ..为noob问题提供支持 – Neil