我有一个使用Database First的Entity Framework的新项目。这是因为它查看了几个不同客户站点上已存在的sql数据。我们有时会发现的一个问题是数据库结束与客户数据库之间存在轻微差异。例如,我们可能有一个可空的字段,并且在某些客户上它的设置为非null,然后在它们的末尾引起EF错误。在我到达他们附近的任何地方之前,我都不知道他们是不同的。
我已经有以下代码循环遍历dbsets但我似乎无法创建一个sql查询,它传递dbset类型以对其运行查询以测试模型是否与数据库匹配,任何人都可以帮助?
System.Data.Entity.Core.Objects.ObjectContext ctx = ((System.Data.Entity.Infrastructure.IObjectContextAdapter)db).ObjectContext;
System.Data.Entity.Core.Metadata.Edm.MetadataWorkspace workspace = ctx.MetadataWorkspace;
IEnumerable<System.Data.Entity.Core.Metadata.Edm.EntityType> tables = workspace.GetItems<System.Data.Entity.Core.Metadata.Edm.EntityType>(System.Data.Entity.Core.Metadata.Edm.DataSpace.SSpace);
foreach (var table in tables)
{
var tableSchema = table.MetadataProperties["TableName"].Value.ToString();
// Need something here to dynamically select all results
// If could pass the Entity Type to db.Database.SqlQuery<type> problem would be solved
}
答案 0 :(得分:0)
您可以使用实体框架的内置方法
context.Database.CompatibleWithModel(true);
或者您可以阅读数据库的systables。
此代码可能与您的sql server不匹配!
SELECT TABLE_NAME, COLUMN_NAME, DOMAIN_NAME, NULLS, WIDTH FROM SYSTABLE LEFT JOIN SYSCOLUMN ON SYSTABLE.TABLE_ID = SYSCOLUMN.TABLE_ID LEFT JOIN SYSDOMAIN ON SYSCOLUMN.DOMAIN_ID = SYSDOMAIN.DOMAIN_ID WHERE SYSTABLE.TABLE_NAME = 'YourTableHere'
此查询将返回表的所有列,类型以及列是否可为空。然后将此查询结果与您的模型进行比较。您可以使用元数据,也可以使用GetProperties
从类中读取属性。
public class DbColumnTypes {
public String TABLE_NAME { get; set; };
public String COLUMN_NAME { get; set; };
public String DOMAIN_NAME { get; set; };
public Boolean ISNULLABLE { get; set; };
}
List<DbColumnTypes> dbColumns; //Read that from your DB
PropertyInfo[] properties = type.GetProperties(BindingFlags.Public).ToArray();
foreach(PropertyInfo item in properties)
{
if(dbColumns.Any(x => x.COLUMN_NAME == item.Name) {
//compare the Database types to the C# types (varchar with string, etc.)
if(item.Property.PropertyType.GetGenericTypeDefinition() == typeof(Nullable<>)
{
//check if database column is nullable
}
}
}
您可以将该代码包装在方法中,并为您在ef模型中的每个类调用它。有了这个,您可以检查您的数据库是否与您的模型匹配。
要获取模型中的所有类型,您可以枚举命名空间中的所有类型:
var theList = Assembly.GetExecutingAssembly().GetTypes().Where(t => t.Namespace == "your.name.space").ToList();
使用此列表,您可以访问所有类并调用上面的方法。