2010-03-15 16 views
13

假設我有一個實體對象定義爲重用LINQ到實體表達<Func鍵<T, TResult>在選擇和轉移呼叫

public partial class Article 
{ 
    public Id 
    { 
     get; 
     set; 
    } 
    public Text 
    { 
     get; 
     set; 
    } 
    public UserId 
    { 
     get; 
     set; 
    } 
} 

根據論文的一些性質,我需要確定該物品可以刪除由給定的用戶。所以我添加一個靜態方法來做檢查。喜歡的東西:

public partial class Article 
{ 
    public static Expression<Func<Article, bool>> CanBeDeletedBy(int userId) 
    { 
     //Add logic to be reused here 
     return a => a.UserId == userId; 
    } 
} 

所以現在我能做的

using(MyEntities e = new MyEntities()) 
{ 
    //get the current user id 
    int currentUserId = 0; 

    e.Articles.Where(Article.CanBeDeletedBy(currentUserid)); 
} 

到目前爲止好。現在我想重新使用邏輯CanBeDeletedBy同時做一個選擇,是這樣的:

using(MyEntities e = new MyEntities()) 
{ 
    //get the current user id 
    int currentUserId = 0; 

    e.Articles.Select(a => new 
    { 
     Text = a.Text, 
     CanBeDeleted = ??? 
    }; 
} 

但無論我怎麼努力,我不能在選擇方法使用表達式。我猜如果我能做

e.Articles.Select(a => new 
    { 
     Text = a.Text, 
     CanBeDeleted = a => a.UserId == userId 
    }; 

然後我應該可以使用相同的表達式。試圖編譯表達式,並通過這樣做來呼叫它

e.Articles.Select(a => new 
    { 
     Text = a.Text, 
     CanBeDeleted = Article.CanBeDeletedBy(currentUserId).Compile()(a) 
    }; 

但它也不起作用。

關於如何使這項工作的任何想法?或者如果這是不可能的,那麼在兩個地方重用業務邏輯的替代方案是什麼?

由於

佩德羅

+0

編譯表達式是正確的選擇,它編譯和爲我工作。如果是我,我也會列出彙編。你遇到了什麼錯誤 ? – 2010-03-15 12:03:04

+0

是的,它編譯得很好,但引發NotSupportedException異常:「LINQ to Entities不支持LINQ表達式節點類型'Invoke'。「 試圖編譯表達式之外的選擇到Func 並在裏面使用它,結果相同。 – Pedro 2010-03-15 12:19:41

+0

順便說一句,如果我使用普通的Func ,並在 – Pedro 2010-03-15 12:24:12

回答

4

使用重新表達式樹是一個黑色藝術;你可以做到這一點,但是你需要將很多代碼切換到反射,並且你會失去所有的靜態檢查。尤其是,使用匿名類型變成噩夢(儘管dynamic在4.0中可能是可行的)。此外,如果你作弊並使用Expression.Invoke,那麼它不被所有提供者支持(最顯着的不是在.NET 3.5SP1中的EF)。

除非這是一個主要的痛點,否則我會留下重複。還是你需要重新使用表達式樹?

+1

Don'不需要重複使用表達式樹,只是嘗試不重複與安全有關的代碼,但現在我會做,並且看看我能否在以後重構代碼 謝謝 – Pedro 2010-03-15 14:01:57

3

我所做的是我用PredicateBuilder這是LinqKit一類,也AsExpandable()http://www.albahari.com/nutshell/linqkit.aspx建立表情和我將它們存儲靜態爲

public readonly Expression<Func<T,bool>> 

在一個靜態類。每個表達式都建立在以前的表達式上,從而減少了重複的數量。

正如Marc Gravell先前的問題所暗示的那樣,這件事是一件黑色的藝術品,但幸好很多作品都是由其他人完成的。

相關問題