2016-07-07 163 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