我从OrmLite开始,现在我正试图看看我是否可以使用Entity Framework Code First做同样的事情。
我遇到了两个无法弄清楚如何使用Entity Framework进行等效的领域。
第一个是我正在使用EntityTypeConfiguration方法。使用OrmLite我可以使用以下POCO:
public List<string> SecondaryPartNumbers { get; set; }
OrmLite会将列表填充到数据库中。我试图按预期存储和检索值和所有工作。当我尝试在Entity Framework POCO中使用相同的行时,我得到了一个intellisense错误:
Property(x => x.SecondaryPartNumbers);
“该类型必须是不可为空的值类型才能将其用作参数'T'”
我找不到任何显示使用EF6执行此操作的示例。我猜测EF6无法使用这些,我将不得不创建另一个POCO并映射以将其规范化为另一个表。我真的很喜欢OrmLite可以使用一个简单的字符串列表,而不必为每个字符串创建表。
我的第二个问题是如何在创建数据库表之后让EF6修改数据库表,以便将varbinary(max)列更改为文件流列。我目前正在将此代码与OrmLite一起使用(感谢hross:OrmLite With Filestream):
public static class OrmLiteFileStreamExtensions
{
/// <summary>
/// WARNING: this will drop all of the existing varbinary columns!
/// </summary>
public static void UpdateByteToBinary<T>(this IDbConnection dbConn)
{
var modelDef = ModelDefinition<T>.Definition;
var tableName = OrmLiteConfig.DialectProvider.GetQuotedTableName(modelDef);
var definitions = modelDef.FieldDefinitions.Where<FieldDefinition>(f => f.FieldType == typeof(byte[]));
foreach (var def in definitions)
{
var columnName = OrmLiteConfig.DialectProvider.GetQuotedColumnName(def.FieldName);
dbConn.ExecuteNonQuery(string.Format("ALTER TABLE {0} ADD [rowguid] [uniqueidentifier] ROWGUIDCOL NOT NULL UNIQUE DEFAULT NEWSEQUENTIALID()", tableName));
dbConn.ExecuteNonQuery(string.Format("ALTER TABLE {0} DROP COLUMN {1}", tableName, columnName));
dbConn.ExecuteNonQuery(string.Format("ALTER TABLE {0} ADD {1} [varbinary](max) FILESTREAM NULL", tableName, columnName));
}
}
}
我一直在寻找DbContext和EntityTypeConfiguration类,看看在创建表之后是否有办法做同样的事情。我看到有Context.Database.ExecuteSqlCommand()看起来是沿着正确的轨道。
我发现看起来很有希望的唯一其他策略是继承现有的初始化程序或从IDatabaseInitializer创建一个并将数据库代码放入重写的Seed()或Initialize()方法中?
但即使使用这个,我也不确定如何找到并遍历查找byte []列的所有实体,然后执行SQL代码来更改表。
以上是否可以在实体框架中使用?我确实找到了引用Entity Framwork的文章,将文件流列视为varbinary(max)但是所有内容似乎都先引用数据库,而不是如何首先从代码中获取表。