EF6代码优先-不能在表中插入标识列的显式值''当IDENTITY_INSERT设置为OFF时
本文关键字:IDENTITY OFF 设置 INSERT 不能 代码 标识 插入 EF6 | 更新日期: 2023-09-27 18:16:39
使用EF6代码-优先:
我的实体:
public class Symbol
{
[Key]
[DatabaseGeneratedAttribute(DatabaseGeneratedOption.None)]
public int Id
{
get; set;
}
public string Name { get; set; }
}
错误:
当IDENTITY_INSERT设置为OFF时,不能在表'Symbols'中插入标识列的显式值。
在谷歌上搜索这个问题时,常见的解决方案是设置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"}
我猜如果我在每次插入之前设置身份插入,这可能会起作用。
只在每次插入
时有没有内置的方法来插入标识而不必在每次插入时手动设置标识插入?
编辑:我也尝试了一些受上面链接启发的东西:
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:
完全放弃DB,然后用
设置它 [Key]
[DatabaseGeneratedAttribute(DatabaseGeneratedOption.None)]
做到了这一点,问题是我在数据库中有重要的数据,不能在每次更改时都删除它。为此,我在迁移之后使用迁移,问题出现了。
编辑:
这似乎解释了问题
迁移不支持身份更改
可能在之前定义了主键,然后在更改其标识设置时根据迁移不工作。
故事的寓意。请确保您的身份在开始时,如果没有删除创建或从链接进行自定义迁移。
关闭数据库中的标识并在代码中管理键值....这是最好的方法