C# EF';无法在对象';更新存储库中的现有对象时

C# EF';无法在对象';更新存储库中的现有对象时,c#,sql,entity-framework,C#,Sql,Entity Framework,我对EF相当缺乏经验,我一直在努力解决一个我确信是相当琐碎的问题,已经有一段时间了。 我有两张桌子,特殊条件和特殊条件部。一个特殊条件可以应用于多个部门,因此我在SpecialConditionDepartment表中存储conditionID和deparmentID。如果条件应用于两个部门,则SpecialConditionDepartment表中将有两行具有相同的条件ID public class SpecialCondition { public int ID { get; set

我对EF相当缺乏经验,我一直在努力解决一个我确信是相当琐碎的问题,已经有一段时间了。 我有两张桌子,特殊条件和特殊条件部。一个特殊条件可以应用于多个部门,因此我在SpecialConditionDepartment表中存储conditionID和deparmentID。如果条件应用于两个部门,则SpecialConditionDepartment表中将有两行具有相同的条件ID

public class SpecialCondition
{
    public int ID { get; set; }
    public string Name { get; set; }
    public virtual ICollection<SpecialConditionDepartment> Departments { get; set; }
}

 public class SpecialConditionDepartment
{
    private SpecialConditionDepartment()
    {
    }

    public SpecialConditionDepartment(int conditionID, int departmentID)
    {
        ConditionID = conditionID;
        DepartmentID = departmentID;
    }

    public int ConditionID { get; set; }
    public int DepartmentID { get; set; }
}


 var specialCondition =modelBuilder.Entity<SpecialCondition>().ToTable("SpecialCondition");
        specialCondition.HasMany(o => o.Departments)
            .WithOptional()
            .HasForeignKey(c => c.ConditionID);

        modelBuilder.Entity<SpecialConditionDepartment>().ToTable("SpecialConditionDepartment")
            .HasKey(c => new { c.ConditionID, c.DepartmentID });
公共类特殊条件
{
公共int ID{get;set;}
公共字符串名称{get;set;}
公共虚拟ICollection部门{get;set;}
}
公共课特殊条件部
{
私人特殊条件部()
{
}
公共特殊条件部门(内部条件ID、内部部门ID)
{
条件ID=条件ID;
部门ID=部门ID;
}
公共int条件ID{get;set;}
public int DepartmentID{get;set;}
}
var specialCondition=modelBuilder.Entity().ToTable(“specialCondition”);
特殊条件。有许多(o=>o.Departments)
.WithOptional()
.HasForeignKey(c=>c.ConditionID);
modelBuilder.Entity().ToTable(“特殊条件部门”)
.HasKey(c=>new{c.ConditionID,c.DepartmentID});
最后,web服务内部的更新方法相当简单。我从数据库中获取对象,更新名称和部门列表,然后使用通用存储库更新()进行更新:

public SpecialConditionDto UpdateCondition(SpecialConditionDto)
{
SpecialCondition SpecialCondition=specialConditionRepository.GetById(dto.ID);
specialcondition.Name=dto.Name;
特殊条件.部门=
地图绘制者(
(部门),;
specialConditionRepository.Update(specialcondition);
unitOfWork.Commit();
返回specialcondition.Map();
}
SpecialConditionRepository继承自RepositoryBase,而后者又继承自IRepository

public class SpecialConditionRepository : RepositoryBase<SpecialCondition>, ISpecialConditionRepository
public abstract class RepositoryBase<T> : IRepository<T> where T : class
公共类特殊条件存储库:RepositoryBase,isSpecialConditionRepository
公共抽象类RepositoryBase:IRepository,其中T:class
以及存储库库,其中定义了所有通用的Add、GetById、Update等

public abstract class RepositoryBase<T> : IRepository<T> where T : class
{
  protected IDbSet<T> Set
  {
    get { return Context.Set<T>(); }
  }

  protected RepositoryBase()
  {
    DatabaseFactory = new DatabaseFactory();
  }
  private EFContext _context;
  public EFContext Context
  {
    get { return _context ?? (Context = DatabaseFactory.Create()); }
    set { _context = value; }
  }
}
public IDbSet<SpecialCondition> SpecialConditions { get; set; }
public IDbSet<SpecialConditionDepartment> SpecialConditionDepartments { get; set; }
公共抽象类RepositoryBase:IRepository其中T:class
{
受保护IDbSet集
{
获取{return Context.Set();}
}
受保护的RepositoryBase()
{
DatabaseFactory=新的DatabaseFactory();
}
私有EFContext\u context;
公共环境
{
获取{return\u context??(context=DatabaseFactory.Create());}
设置{u context=value;}
}
}
上下文中是定义模型和IDBSets的地方

public abstract class RepositoryBase<T> : IRepository<T> where T : class
{
  protected IDbSet<T> Set
  {
    get { return Context.Set<T>(); }
  }

  protected RepositoryBase()
  {
    DatabaseFactory = new DatabaseFactory();
  }
  private EFContext _context;
  public EFContext Context
  {
    get { return _context ?? (Context = DatabaseFactory.Create()); }
    set { _context = value; }
  }
}
public IDbSet<SpecialCondition> SpecialConditions { get; set; }
public IDbSet<SpecialConditionDepartment> SpecialConditionDepartments { get; set; }
公共IDbSet特殊条件{get;set;} 公共IDbSet特殊条件部门{get;set;} 相同的代码用于创建特殊条件。但是,当尝试更新时,它不理解我希望它也更新部门,它试图向SpecialConditionDepartment表添加新行,这最终导致我的代码崩溃


我缺少什么?

好的,首先,我认为我们应该保持简单,只需在数据库中定义两个表:

tdCountry has a CountryId(int, PrimaryKey), CountryName(varchar(128))
tePerson has a PersonId(int), FirstName(varchar(128), LastName(varchar(128)), CountryId(int, ForeignKey to tdCountry(CountryId))
我在EF中这样定义这些关系。我称我的EF容器名为“TesterEntities”以供参考。(稍后显示)

我不确定,但我知道,通常我会将一个工作单元包装在一个上下文中,然后将该上下文暴露出来。这是通过using语句完成的,然后处理它。我也会做我的工作,然后通常引用上下文的“SaveChanges()”,并避免在重命名内容的repo中进行过多的包装。我曾经在一些地方工作过,在那里他们一遍又一遍地重新命名EF正在做的事情,而且在不需要的地方,它增加了复杂性。第二种方法是真正做你需要的事情。本质上,我得到的是我之前刚刚创建的对象。然后我会得到一个需要更新的对象列表。然后,我在与此上下文相关的内存中获取引用中的对象,并将其属性指定给我想要的内容。然后我再次告诉上下文SaveChanges(),它知道如何运行更新

如果您遇到问题,可能是您的引用试图更新的内容太多而不是不够,并且您的对象处于不同的状态。如果你的关系处理不当,你也可能会有问题。通常,如果您正在执行具有“*.edmx”文件的典型显示,您可以观察这些关系


我会尽量远离回购协议,直到你可以在控制台应用程序或更小的功能中验证工作代码。有时候,退一步从头开始重构会有所帮助,而不是处理许多您可能理解或不理解为何以某种方式进行重构的部分。

好的,首先,我认为我们应该保持这一点简单,只需在数据库中定义两个表:

tdCountry has a CountryId(int, PrimaryKey), CountryName(varchar(128))
tePerson has a PersonId(int), FirstName(varchar(128), LastName(varchar(128)), CountryId(int, ForeignKey to tdCountry(CountryId))
我在EF中这样定义这些关系。我称我的EF容器名为“TesterEntities”以供参考。(稍后显示)

我不确定,但我知道,通常我会将一个工作单元包装在一个上下文中,然后将该上下文暴露出来。这是通过using语句完成的,然后处理它。我也会做我的工作,然后通常引用上下文的“SaveChanges()”,并避免在重命名内容的repo中进行过多的包装。我曾经在一些地方工作过,在那里他们一遍又一遍地重新命名EF正在做的事情,而且在不需要的地方,它增加了复杂性。第二种方法是真正做你需要的事情。本质上,我得到的是我之前刚刚创建的对象。然后我会得到一个需要更新的对象列表。然后,我在这个上下文中引用内存中的对象并