C# 更新实体时,实体框架联接表中存在多对多重复值
我有以下代码优先模型:C# 更新实体时,实体框架联接表中存在多对多重复值,c#,.net,entity-framework,C#,.net,Entity Framework,我有以下代码优先模型: public class Model1 : DbContext { public Model1() : base("name=Model1") { } public virtual DbSet<Master> Masters { get; set; } public virtual DbSet<Slave> Slaves { get; set; } protected overri
public class Model1 : DbContext
{
public Model1()
: base("name=Model1")
{
}
public virtual DbSet<Master> Masters { get; set; }
public virtual DbSet<Slave> Slaves { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<Master>().Property(e => e.Id).HasDatabaseGeneratedOption(DatabaseGeneratedOption.None);
modelBuilder.Entity<Slave>().Property(e => e.Id).HasDatabaseGeneratedOption(DatabaseGeneratedOption.None);
modelBuilder.Entity<Master>().Property(e => e.Name).IsRequired();
modelBuilder.Entity<Slave>().Property(e => e.Name).IsRequired();
}
}
public interface IEntity
{
int Id { get; }
}
public class Master : IEntity
{
public int Id { get; set; }
public string Name { get; set; }
public virtual ICollection<Slave> Slaves { get; set; }
public Master()
{
Slaves = new EntityHashSet<Slave>();
}
public Master(string name)
: this()
{
Id = name.GetHashCode();
Name = name;
}
public void Update(IEnumerable<Slave> slaves, Model1 model)
{
Slaves = new EntityHashSet<Slave>(slaves.Select(s => model.Slaves.CreateOrFind(s)));
}
public void Update(IEnumerable<string> slaves, Model1 model)
{
Update(slaves.Select(s => new Slave(s)), model);
}
}
public class Slave : IEntity
{
public int Id { get; set; }
public string Name { get; set; }
public virtual ICollection<Master> Masters { get; set; }
public Slave()
{
Masters = new EntityHashSet<Master>();
}
public Slave(string name)
: this()
{
Id = name.GetHashCode();
Name = name;
}
}
当我尝试对现有方法使用update方法时,会抛出DbUpdateException:
using (var model = new Model1())
{
var m = new Master("master1");
m.Update(new[] {"slave1", "slave2", "slave3"}, model);
model.Masters.Add(m);
model.SaveChanges();
}
var m = model.Masters.CreateOrFind(new Master("master1"));
m.Update(new[] {"slave1", "slave2", "slave3", "slave4"}, model);
model.SaveChanges();
其他信息:保存未公开其关系的外键属性的实体时出错。EntityEntries属性将返回null,因为无法将单个实体标识为异常源。通过在实体类型中公开外键属性,可以更轻松地在保存时处理异常。有关详细信息,请参见InnerException
相关内部例外情况:
违反主键约束“PK_dbo.slavemasts”。无法在对象“dbo.SlaveMasters”中插入重复密钥。重复的键值是(1928309069,-2136434452)。
声明已终止
为什么会这样?我正在检查数据库中是否已经存在实体,或者是否需要通过CreateOrFind创建实体
编辑:为了澄清,产生错误的行是:
Slaves = new EntityHashSet<Slave>(slaves.Select(s => model.Slaves.CreateOrFind(s)));
Slaves=newentityhashset(Slaves.Select(s=>model.Slaves.CreateOrFind(s));
调用SaveChanges()时引发错误。您必须使用以前的ef配置文件,因此它将始终尝试插入相同的值,但会更新。
您可以在更新之前更新或检查ef配置文件。我认为您必须使用以前的ef配置文件,因此它将始终尝试插入相同的值,但会进行更新。
您可以在更新之前更新或检查ef配置文件。发现了一种解决此问题的肮脏方法。在创建新EntityHashSet之前,我调用原始SQL命令,从包含当前主Id的SlaveMasters表中删除条目
model.ExecuteSqlCommand("DELETE FROM SlaveMasters WHERE Master_Id = " + Id);
Slaves = new EntityHashSet<Slave>(slaves.Select(s => model.Slaves.CreateOrFind(s)));
model.ExecuteSqlCommand(“从SlaveMasters中删除,其中Master_Id=“+Id”);
Slaves=newentityhashset(Slaves.Select(s=>model.Slaves.CreateOrFind(s));
找到了一个不好的方法来解决这个问题。在创建新EntityHashSet之前,我调用原始SQL命令,从包含当前主Id的SlaveMasters表中删除条目
model.ExecuteSqlCommand("DELETE FROM SlaveMasters WHERE Master_Id = " + Id);
Slaves = new EntityHashSet<Slave>(slaves.Select(s => model.Slaves.CreateOrFind(s)));
model.ExecuteSqlCommand(“从SlaveMasters中删除,其中Master_Id=“+Id”);
Slaves=newentityhashset(Slaves.Select(s=>model.Slaves.CreateOrFind(s));
您所说的“ef配置文件”是什么意思?您所说的“ef配置文件”是什么意思?