2011-08-12 33 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

相关问题