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
}
};
精彩评论