// EDMX文件 http://pastebin.com/btTCRMf7
我有2个表Customers
和Sites
//Site
public int ID { get; set; }
public string Name { get; set; }
public string Address { get; set; }
public int CustomerID { get; set; }
public int CityID { get; set; }
public int CountryID { get; set; }
public int EncodedBy { get; set; }
public System.DateTime DateEncoded { get; set; }
public virtual City City { get; set; }
public virtual Country Country { get; set; }
public virtual ICollection<Invoice> Invoices { get; set; }
public virtual User User { get; set; }
public virtual Customer Customer { get; set; }
//Customer
public int ID { get; set; }
public string Name { get; set; }
public string Address { get; set; }
public int CityID { get; set; }
public int CountryID { get; set; }
public int CreditTermID { get; set; }
public int EncodedBy { get; set; }
public System.DateTime DateEncoded { get; set; }
public virtual City City { get; set; }
public virtual Country Country { get; set; }
public virtual CreditTerm CreditTerm { get; set; }
public virtual User User { get; set; }
public virtual ICollection<Invoice> Invoices { get; set; }
public virtual ICollection<Site> Sites { get; set; }
//Country
public int ID { get; set; }
public string Name { get; set; }
public virtual ICollection<Customer> Customers { get; set; }
public virtual ICollection<Site> Sites { get; set; }
//City
public int ID { get; set; }
public string Name { get; set; }
public virtual ICollection<Customer> Customers { get; set; }
public virtual ICollection<Site> Sites { get; set; }
//SiteModel
private static IQueryable<Site> Build(this DbSet<Site> query)
{
return query.Include("User").Include("City").Include("Country").Include("Customer");
}
public static Site Find(int siteID)
{
using (DragonRentalsEntities context = new DragonRentalsEntities(new ConfigurationManager().ConnectionString))
{
Site result = context.Sites.Build().SingleOrDefault(s => s.ID == siteID);
return result;
}
}
public static Site Update(Site _updatedSite)
{
using (DragonRentalsEntities context = new DragonRentalsEntities(new ConfigurationManager().ConnectionString))
{
context.Sites.Attach(_updatedSite);
context.Entry(_updatedSite).State = EntityState.Modified;
context.SaveChanges();
return Find(_updatedSite.ID);
}
}
Site test = SiteModel.Find(1);
test.City = null;
test.CityID = 1;
test.Country = null;
test.CountryID = 1;
test.Customer = null;
test.CustomerID = 1;
SiteModel.Update(test);
我正在A referential integrity constraint violation occurred: The property values that define the referential constraints are not consistent between principal and dependent objects in the relationship.
但是,在更新对象之前添加test.Customer.City = null;
会起作用。似乎Customer.City和Site.City是冲突的。谁能解释一下为什么?或任何解决方法?
答案 0 :(得分:2)
我可以解释原因。包括持久化实体以加载所有包含对象。因此,我们的站点对象具有对您的群集(城市,国家/地区,用户客户)的所有引用。我认为这就是问题所在。解决方案可以是只加载站点对象:
Site result = context.Sites.SingleOrDefault(s => s.ID == siteID);
因此它只会加载网站对象的ID。您可以在运行时根据需要加载引用的对象。
我认为这是因为当您使用include时,您操作对象和对象集合dbContext跟踪此更改并在您调用时保存它们
context.SaveChanges();
有点重构的代码btw:
public static Site Update(Site _updatedSite)
{
using (DragonRentalsEntities context = new DragonRentalsEntities(new ConfigurationManager().ConnectionString))
{
if (context.Entry(_updatedSite).State == EntityState.Detached)
context.Entry(_updatedSite).State = EntityState.Modified;// attaches entity and marks it as modified if it is detached
context.SaveChanges();
return _updatedSite; //after save changes u have the same object as u send in your Update function
}
}
评论答案 Slauma如果我没有将它设置为null,我将无法在更新方法中附加它们,同样的错误将被触发
的答案:强> 的 因为当您包含已附加到上下文对象的所有实体时。 Btw Include转换sql内部连接语句,因此你的db对象的快照可能不包含具有该ID的City。