2012-03-28 17 views
1

這是基於前一個問題我有:EF Code First implemented interface property通用約束和表達式類型評價

我有這樣的事情。

interface IKeywordedEntity 
{ 
    ICollection<Keyword> Keywords { get; } 
} 
class Foo : EntityBase, IKeywordedEntity 
{ 
    public virtual ICollection<Keyword> Keywords { get { ... } } 
} 

EntityBase的細節並不重要。

起初,我寫了這個擴展方法讓事情幹:

public static void WithKeywords<TEntityType>(this EntityTypeConfiguration<TEntityType> 
    entityTypeConfiguration) where TEntityType : EntityBase, IKeywordedEntity 
{ 
    entityTypeConfiguration.HasMany(e => e.Keywords).WithMany(); 
} 

我會調用它像這樣:

modelBuilder.Entity<Foo>.WithKeywords(); 

然而,實體框架或C#編譯器是在lambda治療e作爲IKeywordedEntity而不是TEntityType。這嚇壞了實體框架。

瞭解了這一點,我嘗試了手動將lambda作爲Expression寫入HasMany。我想出了以下內容:

public static void WithKeywords<TEntityType>(this EntityTypeConfiguration<TEntityType> 
    entityTypeConfiguration) where TEntityType : EntityBase, IKeywordedEntity 
{ 
    var rootExpression = Expression.Parameter(typeof (TEntityType)); 
    var expression = Expression.Property(rootExpression, "Keywords"); 

    entityTypeConfiguration.HasMany(Expression.Lambda<Func<TEntityType, ICollection<Keyword>>>(expression, rootExpression)).WithMany(); 
} 

現在的智能感知正顯示出我的EntityBaseIKeywordedEntity組合正確,並告訴我說,eTEntityType

我的問題是:爲什麼通過/編譯表達式樹從lambda對待eIKeywordedEntity,而不是TEntityType

回答

0

我不是Expressions和Lambdas的專家,但這是我認爲正在發生的事情。

當我們只是指定一個lambda來將它轉換爲一個表達式樹時,編譯器會執行將事物轉換爲樹的工作。在方法體中所有的編譯器可以看到的是IKeyworkedEntity.KeywordsTEntityType.Keywords,它使用明確的屬性名稱,即使用以下

var rootExpression = Expression.Parameter(typeof (IKeyworkedEntity)); 
var expression = Expression.Property(rootExpression, "Keywords"); 

,是造成我們看到的問題。現在,如果我們自己構建表達式樹,我們知道在TEntityType上有一個屬性,我們在樹中這麼說。這會導致遷移通過,因爲它在類上而不是在界面上查看屬性。