EF 4.1,POCO:有什么方法可以在运行时获取表名称以避免硬编码?

发布于 2024-11-29 10:58:25 字数 250 浏览 0 评论 0原文

我在实体框架中使用 POCO。最新的 EF 版本中是否有任何直接或间接的方法可以在运行时获取表名称以避免硬编码值?

我需要它在我的自定义数据库初始化程序中运行这样的代码:

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

谢谢

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

私野 2024-12-06 10:58:25

我假设您的上下文与我的上下文类似,当您将 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 覆盖)。

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).

战皆罪 2024-12-06 10:58:25

POCO 意味着您可以在数据模型中使用“普通”CLR 对象 (POCO),例如现有的域对象。这些 POCO 数据类(也称为持久性无知对象)映射到数据模型中定义的实体,并且根据定义,它不应与数据库实现细节直接相关。但是,您可以使用常量类和 Fluent 映射来以更好的方式满足您的需求

您的常量类实现

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

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))
才能让你更想念 2024-12-06 10:58:25

看看这个讨论有多“活跃”,在我看来,当前版本的 EF 中并未提供此功能。我希望此功能将在 EF 的未来版本之一中提供。

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.

无悔心 2024-12-06 10:58:25

这段代码到底有用吗?

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

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
                   }
        };
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文