2017-03-03 50 views
1

我使用的是在網上看到的教程庫模式...如何使用類型Func鍵的表達調用方法參數

一切工作正常,除了find方法,我不知道如何與這和我的工作我很難理解表達式或函數類型。我用之前LINQ和拉姆達但我初學者,但仍沒有流利地使用它...

public IEnumerable<TEntity> Find(Expression<Func<TEntity, bool>> predicate) 
{ 
    return Context.Set<TEntity>().Where(predicate); 
} 

我有這個模型類:

public partial class Artikl 
{ 
     [Browsable(false)] 
     public int IDArtikli { get; set; } 
     public string Barkod { get; set; } 
     [DisplayName("Šifra")] 
     public Nullable<int> Sifra { get; set; } 
     public string Naziv { get; set; } 
     [DisplayName("JM")] 
     public string JedinicaMjere { get; set; } 
     public decimal Tarifa { get; set; } 
     [DisplayName("Prodajna")] 
     public Nullable<decimal> ProdajnaCijena { get; set; } 
     [Browsable(false)] 
     public Nullable<bool> Flag { get; set; } 
     public Nullable<decimal> Kalo { get; set; } 
     [DisplayName("Nabavna")] 
     public Nullable<decimal> NabavnaCijena { get; set; } 
     [DisplayName("Veleprodajna")] 
     public Nullable<decimal> VeleprodajnaCijena { get; set; } 
     public Nullable<decimal> Zalihe { get; set; } 
} 

我的問題是如何能得到Artikl物品基於財產「Sifra」。我不知道如何調用該方法...

private void txtSifra_TextChanged(object sender, EventArgs e) 
{ 
    var artikl = _UnitOfWork.Artikl.Find(???); 
    txtNaziv.Text = artikl.Naziv; 
} 

回答

2

你需要傳遞一個lambda expression滿足Expression<Func<TEntity, bool>> predicate。您可以通過以下方式獲得基於屬性「Sifra」的物品:

var artikl = _UnitOfWork.Artikl.Find(q => q.Sifra == "some int value").FirstOrDefault(); 

希望它有幫助!

+0

謝謝,但我不得不添加First()在末尾 – ChenChi

+2

哦。對不起,但在這種情況下,我建議你使用FirstOrDefault(),所以它不會導致一些崩潰。當你的Find()沒有返回任何東西會導致崩潰的時候使用First()。 – mindOfAi

1

Expression<Func<TEntity, bool>>用法像這樣,只是傳遞一個lambda表達式(僞代碼):

var result = context.set.Find(x => x.Property == value); 

所以你的情況:

var artiklList = _UnitOfWork.Artikl.Find(x => x.Sifra == 1); 
var artikl = artiklList.FirstOrDefault(); 

不要忘了返回.FirstOrDefault()因爲Find結果將是IEnumerable<T>

3

其他的答案已經解釋瞭如何使用的表達,但我想提一件事使用所謂的存儲庫模式時,常常被忽視:

public IEnumerable<TEntity> Find(Expression<Func<TEntity, bool>> predicate) 
{ 
    return Context.Set<TEntity>().Where(predicate); 
} 

這將返回IEnumerable<TEntity>正因爲這個:

var result = _UnitOfWork.Artikl.Find(c => c.Sifra == 1).FirstOrDefault() 

不是在數據庫中執行整個查詢。該數據庫查詢將如下(大致)是這樣的:

select * from Artikl where Sifra = 1 -- < not efficient 

,而不是像這樣:

select top 1 * from Artikl where Sifra = 1 -- < efficient 

要解決這個問題,你必須要麼返回IQueryable

public IQueryable<TEntity> Find(Expression<Func<TEntity, bool>> predicate) 
{ 
    return Context.Set<TEntity>().Where(predicate); 
} 

或做您將要進行的每個查詢的單獨方法:

public TEntity FindFirst(Expression<Func<TEntity, bool>> predicate) 
{ 
    return Context.Set<TEntity>().Where(predicate).FirstOrDefault(); 
} 
+0

爲什麼「select * from Artikl where Sifra = 1」效率不高?我不明白你想指出嗎? – ChenChi

+0

@ChenChi,http://stackoverflow.com/questions/2876616/returning-ienumerablet-vs-iqueryablet - 這是用貪婪的方式從DB中加載太多記錄到內存中。 – G0dsquad

+3

@ChenChi我試着指出,「從Sikra = 1的Artikl中選擇** top 1 **」比僅從Sikra = 1的Artikl中選擇*效率更高。如果您返回IEnumerable並稍後使用FirstOrDefault - 後面的查詢將被執行。最糟糕的部分是,它很可能會被忽視,直到您將進行大量查詢或當您的表格變大時(例如在您將代碼從開發發佈到生產時)。 – Evk

相關問題