2011-08-12 30 views
3

我在實體框架中使用POCO。在最新的EF版本中,是否有任何直接或間接的方式在運行時獲取表名以避免硬編碼值?EF 4.1,POCO:有沒有辦法在運行時獲得表名以避免硬編碼?

我需要我的自定義數據庫初始化裏面像這樣運行代碼:

context.Database.ExecuteSqlCommand(
    string.Format("DBCC CHECKIDENT ({0}, RESEED, {1})", tableName, newSeed)) 

感謝

+0

你可以從你的數據庫初始化器發佈一個樣本,並解釋你想要改變什麼? –

+0

@marc_s:context.Database.ExecuteSqlCommand(string.Format(「DBCC CHECKIDENT({0},RESEED,{1})」,tableName,newSeed)) – YMC

+1

請**不要**將代碼和內容放入註釋 - 它真的**很難閱讀。相反:**更新**您的原始問題**編輯**並提供更多信息! –

回答

1

我從你的情況下看起來像我的,與每個表名的假設工作充分利用類名當您添加DbSet到您的環境下生成的。如果是這樣的話,你可以用反射實現自己的目標,雖然這是一個有點難看:

public class MyContext : DbContext 
{ 
    public MyContext() : base("MyDatabase") 
    { 
    } 

    public DbSet<Video> Video { get; set; } 
    public DbSet<VideoRating> Rating { get; set; } 
    public DbSet<User> User { get; set; } 

      protected override void OnModelCreating(DbModelBuilder modelBuilder) 
    { 
     modelBuilder.Conventions.Remove<PluralizingTableNameConvention>(); 
    } 

    public class Initializer : IDatabaseInitializer<DashVaultContext> 
    { 
     public void InitializeDatabase(MyContext context) 
     { 
      if (!context.Database.Exists()) 
      { 
       context.Database.Create(); 

       PropertyInfo[] propertyInfos = typeof(MyContext).GetProperties(BindingFlags.DeclaredOnly | 
       BindingFlags.Public | BindingFlags.Instance); 

       var newSeed = 1000; // Or whatever is appropriate 

       foreach (PropertyInfo propertyInfo in propertyInfos) 
       { 
        var tableName = propertyInfo.PropertyType.GetGenericArguments()[0].Name; 
        context.Database.ExecuteSqlCommand(
         string.Format("DBCC CHECKIDENT ({0}, RESEED, {1})", tableName, newSeed)); 
       } 
      } 
     } 
    } 
} 

更新:我刪除了多元化的黑客,只是關閉在生成的表名稱多元化(見OnModelCreating覆蓋)。

+0

對,有些我們的類被映射到帶有「s」的表名,其中一些沒有。無論如何感謝這個想法。 – YMC

+0

@YMC我更新了我的答案,使其更加健壯 - 我只是否決了OnModelCreating以關閉表名的複數化。這樣,班級名稱始終是表格的名稱,我的答案將始終有效。當然,這是假設你可以用表名永遠是類名。 –

+0

好吧,雖然它可能看起來有點奇怪的解決方法來解決任務,至少它適用於我。謝謝 – YMC

0

POCO意味着您可以使用「純老」 CLR對象(PO​​CO),如現有的域對象,與您的數據模型。這些POCO數據類(也稱爲持久性無關對象)映射到在數據模型中定義的實體,並且根據定義,它不應與數據庫實現細節直接相關。但是,你可以使用常量類和流利的映射,以便以更好的方式

你不變類實現

public static class Constant 
{ 
public const string CreditCustomer = "dbo.CreditCustomer"; 
} 

你的映射是這樣的

builder.Entity<Customer>() 
.HasKey(c => c.ID) 
.MapSingleType(c => new { 
    cid = c.ID, 
    nme = c.Name 
    } 
) 
.ToTable(Constant.Table.CreditCustomer); 

在你dbInitializer

您的要求
context.Database.ExecuteSqlCommand(
string.Format("DBCC CHECKIDENT ({0}, RESEED, {1})", Constant.Table.CreditCustomer, newSeed)) 
+0

對,這是我一直在使用的解決方法。問題是通過EF配置類找出表名來除掉那個Constant類的任何直接方法,我不想爲每個表創建常量,我希望我的表名在我更改通信域類後立即自動更新名稱。 – YMC

0

看看這個討論如何「活躍」 ,在我看來,這個功能僅僅在當前版本的EF中沒有提供。我希望這個功能可以在EF的未來版本中使用。

0

此代碼有用嗎?

 var query = from meta in context.MetadataWorkspace.GetItems(DataSpace.SSpace) 
      .Where(m => m.BuiltInTypeKind == BuiltInTypeKind.EntityType) 
     let properties = meta is EntityType ? (meta as EntityType).Properties : null 
     select new 
     { 
      TableName = (meta as EntityType).Name, 
      Fields = from p in properties 
        select new 
        { 
        FielName = p.Name, 
        DbType = p.TypeUsage.EdmType.Name 
        } 
     }; 
+0

什麼是MetadataWorkspace? DbContext沒有這樣的屬性 – YMC

+0

檢查以下鏈接。它描述了從DbContext鏈接到ObjectContext的可能方法,其中MetadataWorkspace可用:http://blog.davidebbo.com/2011/01/using-dynamic-data-with-ef-code-first.html – Paul

相關問題