2011-02-19 43 views
2

我有許多實體對象在結構上相同,但命名約定不同,例如Products1,Products2,Products3(這是傳統數據庫模式的一部分,我不能做太多這方面的工作)。按名稱檢索實體對象 - LINQ to Entities,EF 4.0

就CLR而言,這些類是不同類型的,不幸的是,由於設計代碼是自動生成的,所以我不能對這些傢伙的界面進行拍照以顯示通用性。所以,我的問題是:有沒有辦法通過名稱檢索實體對象?

我基本上喜歡避免開關/案件業務,當這些對象應用基本相同的邏輯。

回答

0

根據我們談論的班級數量以及您需要的靈活程度,界面可能不會出問題。我已經使用泛型做了類似的事情:

//WARNING: Partially-remembered code ahead... 
interface IDuckEntity 
{ 
    int FeatherCount { get; set; } 
} 

public partial class Products1 : IDuckEntity { } 
public partial class Products2 : IDuckEntity { } 
public partial class Products3 : IDuckEntity { } 

//in some other class: 
void DoStuff<T>(T entity) where T : EntityObject, IDuckEntity 
{ 
    entity.FeatherCount = 500; 
} 

因此,基本上,你建立你把接口和一幫那些小部分類聲明的一個單獨的文件。然後你就可以使用通用結構。我不知道你的確切情況,但這對我來說就像是一種魅力。

1

由於EF4類是部分類,所以實際上可以擴展它們並使它們實現您所選擇的接口,所有這些都在單獨的文件中。

另一種方法是使用dynamic - 只是根據實體的類型實例化實體。

dynamic myEntity= Activator.CreateInstance(Type.GetType("EntityTypeHere"))); 
myEntity.CommonProperty = "Foo"; 

的最大缺點這裏是你失去在編譯時的所有類型安全 - 你只會在運行時發現任何問題,也它比靜態類型的方法要慢。

2

你可以建立一個表達式樹來查詢有問題的對象或對象:

public T GetSingleObject<T>(int someValue) { 
    MyEntities db = new MyEntities(); 
    var result = db.CreateQuery<T>(String.Format("[{0}]", typeof(T).Name + "s")); 

    var param = Expression.Parameter(typeof(T)); 

    var lambda = Expression.Lambda<Func<T, bool>>(
     Expression.Equal(
      Expression.Property(param, "WhateverPropertyYourComparing"), 
      Expression.Constant(someValue)), 
     param); 

    return result.SingleOrDefault(lambda); 
} 

或者,如果你希望對象

public IEnumerable<T> GetResultCollection<T>(int someValue) { 
    MyEntities db = new MyEntities(); 
    var result = db.CreateQuery<T>(String.Format("[{0}]", typeof(T).Name + "s")); 

    var param = Expression.Parameter(typeof(T)); 

    var lambda = Expression.Lambda<Func<T, bool>>(
     Expression.Equal(
      Expression.Property(param, "WhateverPropertyYourComparing"), 
      Expression.Constant(someValue)), 
     param); 

    return result.Where(lambda); 
} 

當然的集合,如果你想要查詢非常長久以來,這可能會失控,你應該考慮使用部分類來添加必要的接口,就像Justin Morgan所建議的那樣。

請注意,此方法假定您的ObjectSet集合與您的對象名稱相同,再加上一個「s」,即「Invoice」到「Invoices」。如果不是這種情況,即從「人員」到「人員」,那麼您可以使用System.Data.Entity.Design.PluralizationServices.PluralizationService獲取專有名稱