首先使用EF6代码:
我的实体:
public class Symbol
{
[Key]
[DatabaseGeneratedAttribute(DatabaseGeneratedOption.None)]
public int Id
{
get; set;
}
public string Name { get; set; }
}
错误:
当IDENTITY_INSERT设置为OFF时,无法在表'符号'中为标识列插入显式值。
在Google上搜索问题的常见解决方案是设置DatabaseGeneratedOption.Identity
。
由于我不能告诉DB不为我生成身份,这没有意义
导致奇怪的副作用。它正在生成一个正在运行的身份,从我离开的地方开始运行。即使我删除了表中的所有实体。
场景:
1) inserting { 44, "s1"} , { 55, "s2"} , { 52, "s3"}
In DB : {1,"s1"} {2,"s2"} {3,"s3"}
2) delete all symbols
3) inserting { 44, "s1"} , { 55, "s2"} , { 52, "s3"}
In DB : {4,"s1"} {5,"s2"} {6,"s3"}
我猜我是否在每次插入之前设置了Identity插入,这可能会起作用。
Like in this answer only on each insert
是否有任何内置的方式来插入标识而不必在每个插入上手动设置标识插入?
编辑:
我也尝试过以上链接启发的内容:
public void InsertRange(IEnumerable<TEntity> entities)
{
_context.IdentityInsert<TEntity>(true);
_dbSet.AddRange(entities);
_context.SaveChanges();
_context.IdentityInsert<TEntity>(false);
}
public static string GetTableName<T>(this DbContext context) where T : class
{
ObjectContext objectContext = ((IObjectContextAdapter) context).ObjectContext;
return objectContext.GetTableName<T>();
}
public static string GetTableName<T>(this ObjectContext context) where T : class
{
string sql = context.CreateObjectSet<T>().ToTraceString();
Regex regex = new Regex(@"FROM\s+(?<table>.+)\s+AS");
Match match = regex.Match(sql);
string table = match.Groups["table"].Value;
return table;
}
public static void IdentityInsert<T>(this DbContext context ,bool on) where T : class
{
if (on)
{
context.Database.ExecuteSqlCommand(string.Concat(@"SET IDENTITY_INSERT ", context.GetTableName<T>(), @" ON"));
}
else
{
context.Database.ExecuteSqlCommand(string.Concat(@"SET IDENTITY_INSERT ", context.GetTableName<T>(), @" OFF"));
}
}
它不起作用
编辑2:
完全丢弃数据库,然后使用
进行设置 [Key]
[DatabaseGeneratedAttribute(DatabaseGeneratedOption.None)]
做了诀窍,问题是我在该数据库中获得了重要数据,并且不能在每次更改时放弃它。为此我在迁移后使用迁移问题出现了。
编辑:
这似乎解释了这个问题
Migrations don't support identity change.
当我更改其身份设置时,可能之前已定义主键,然后根据迁移不起作用。
故事的寓意。如果不是删除创建或从链接执行自定义迁移,请确保您的身份在开头。
答案 0 :(得分:1)
关闭数据库中的身份并管理代码中的键值.... 这是最好的方法