2013-12-19 43 views
0

我正試圖寫一些對我來說簡單的場景。在我們的大多數應用程序中,我們有一個允許用戶編輯下拉列表值的系統 - 查找表。如何通過表的字符串名稱查詢EF中的表?

下拉表通常非常小,僅僅由幾個領域:

  • ID(PK,INT身份1,1)
  • 說明(爲nvarchar)
  • LastModifiedBy(爲nvarchar )
  • LastModifiedDate(SMALLDATETIME)

他們可能有無ADDI各個領域顯然會有所不同。 id,LastModifiedBy和LastModifiedDate屬性都在一個基本實體類中定義,我們所有其他實體從該實體類派生出來。

我們需要能夠查詢一個實體的EF上下文,這個實體除了三個公共字段外,在運行時直到完全是未知的(包括名稱/類型和字段)。這否定了泛型,這是非常棒的。我們能夠自己解決很多反射問題 - 這將處理未知的列,因爲我們可以列舉我們的屬性並從那裏出發。我們看到的更難的問題是試圖查詢EF,並在我們直到運行時才知道表時才返回可序列化的實體。

所以我想問這個最簡單的方法是:我怎樣才能查詢EF,並獲得一個可序列化的實體,使用實體的字符串名稱?

我們正在尋找實現是一個方法的簽名看起來是這樣的:

public BaseEntity RetrieveEntity(string entityType, int? id); 

一旦我們在地方的核心,我們應該能夠輕鬆地適應我們的其他情形(插入,更新,檢索網格的分頁列表等)。

只要我們有一些具體的工作,我們可以使用上面的表格定義。我們會打電話給實體StatusCode,並承擔其定義如下:

public partial class StatusCode : BaseEntity // BaseEntity gives us id, LastModifiedBy, LastModifiedDate 
{ 
    public string StatusCodeDescription { get; set; } 
} 

public class StatusCodeMap : EntityTypeConfiguration<StatusCode> 
{ 
    // boilerplate comments removed for brevity 
    this.HasKey(t => t.id); 

    this.Property(t => t.StatusCodeDescription) 
     .IsRequired() 
     .HasMaxLength(255); 

    this.ToTable("StatusCode"); 
    this.Property(t => t.id).HasColumnName("StatusCodeId"); 
    this.Property(t => t.StatusCodeDescription).HasColumnName("StatusCodeDescription"); 
    this.Property(t => t.LastModifiedBy).HasColumnName("LastModifiedBy"); 
    this.Property(t => t.LastModifiedDate).HasColumnName("LastModifiedDate"); 
} 

IF我可以明確指出,所有的下拉菜單將有一個描述,不出意外的話我可以創造一個抽象類從下拉列表中導出並處理。儘管如此,我仍然必須能夠通過名稱動態查詢並檢索該對象的實例。誠然,我不能保證這是事實。其中一些有其他字段 - 布爾屬性在這裏或那裏,也許代碼映射到描述用於後端集成等。所以只使用基類不是解決方案,並且不會充分發揮。 PS:我敢肯定,這其實是一個騙局。我知道我不能成爲第一個遇到這個問題的人。如果我們能夠在SO上的其他地方找到解決方案,我很樂意關閉它。但是,我花了整整一個下午的時間在Google上尋找解決這個問題的整體解決方案,並且失敗了。也就是說,我的Google-Fu今天可能會讓我失望。

+0

通用DbSet這可能幫助:http://stackoverflow.com/q/19259299/139917 – DaveB

+0

@DaveB:謝謝,我想一些方法中有可能會。 –

回答

1

你說你有一個BaseEntity類,所有這些類都從它繼承。

你使用的是什麼類型的繼承? TPH?

您是否在上下文中添加了public DbSet<BaseEntity> BaseEntities { get; set; }

我敢肯定,如果你這樣做,那麼你的方法可以這樣實現:

public BaseEntity RetrieveEntity(string entityType, int? id) 
{ 
    var e = context.BaseEntities.Find(id.GetValueOrDefault(-1)); 
    if(e.GetType() != entityType) 
     return null; 

    return e; 
} 

不知道爲什麼你會想這樣做,雖然。我有這樣的:

public BaseEntity RetrieveEntity(int id) 
{  
    return context.BaseEntities.Find(id); 
} 

,並使用它像這樣

StatusCode sc = RetrieveEntity(int id) as StatusCode; 
if(sc != null) 
    //etc 

或本:

public T RetrieveEntity<T>(int id) where T: BaseEntity 
{ 
    return context.BaseEntities.Find(id) as T 
} 

,並使用它像這樣:

StatusCode sc = RetrieveEntity<StatusCode>(int id) 
if(sc != null) 
    //etc 

編輯 o R您可以只使用這樣

public T RetrieveEntity<T>(int id) where T: BaseEntity 
{ 
    return context.DbSet<T>().Find(id) 
} 
+0

這感覺就像它不會玩。我的意思是,是的,我可以調整它以在列表中工作,但我沒有看到基類的DbSet(它本身不對應於任何地方的表格)將如何實際發揮出來。 EF將不得不將我們所做的任何事情轉換成一個SQL查詢打到一張表 - 並且它需要知道要打哪個表。也許我在這裏錯過了一些東西? –

+0

儘管有上述評論,儘管我不認爲你有我的答案,但是你有*最重要的東西成了我的答案:你提供了TPH文章的鏈接。雖然我們沒有使用真正的TPH方法,但是它向我展示瞭如何構建實體SQL,以便我們能夠獲得我們的對象......並且所有事情都已經很好了。光在隧道盡頭,謝謝! –

+0

沒有表格意味着不是TPH。你看過TPC嗎? http://weblogs.asp.net/manavi/archive/2011/01/03/inheritance-mapping-strategies-with-entity-framework-code-first-ctp5-part-3-table-per-concrete-type- tpc-and-choosing-strategy-guidelines.aspx,但這可能是矯枉過正。你不能只使用通用的DbSet?查看我的編輯 – Colin

相關問題