开发者

EF 4.1, POCO: Is any way to get Table name in runtime to avoid hardcode?

开发者 https://www.devze.com 2023-03-27 23:11 出处:网络
I use开发者_运维知识库 POCO in Entity Framework. Is any direct or indirect way in the latest EF version to get Table name at the runtime to avoid hardcode values?

I use开发者_运维知识库 POCO in Entity Framework. Is any direct or indirect way in the latest EF version to get Table name at the runtime to avoid hardcode values?

I need it inside my custom database initializer to run code like this:

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

Thanks


I'm working from the assumption that your context looks something like mine, with each of the table names getting generated from the class names when you add a DbSet to your context. If that's the case, you can achieve your goal with reflection, though it's a little ugly:

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));
                }
            }
        }
    }
}

UPDATE: I removed the pluralization hack and just turned off pluralization in the generated table names (see the OnModelCreating override).


POCO means you can use "plain-old" CLR objects (POCO), such as existing domain objects, with your data model. These POCO data classes (also known as persistence-ignorant objects), which are mapped to entities that are defined in a data model and by definition it shouldn't be directly related to database implementation details. However, you can use constant class and Fluent mapping to facilitate your requirement in a better way

Your constant class implementation

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

Your mappings goes like this

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

In your dbInitializer

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


Looking at how "active" this discussion is, it seems to me this functionality is just not provided in the current version of EF. I hope this features will be available in one of future version of EF.


Will this code be useful at all?

        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

精彩评论

暂无评论...
验证码 换一张
取 消