简体   繁体   English

外键冲突

[英]Foreign key conflict

//EDMX File http://pastebin.com/btTCRMf7 // EDMX文件http://pastebin.com/btTCRMf7

I have 2 tables Customers and Sites 我有2张桌子CustomersSites

//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);

i am getting 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. 我越来越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.

however, adding test.Customer.City = null; 但是,添加test.Customer.City = null; before updating the object would work. 在更新对象之前,它将起作用。 it seems like Customer.City and Site.City is conflicting. 似乎Customer.City和Site.City发生冲突。 can somebody explain why? 有人可以解释为什么吗? or any workaround? 或任何解决方法?

I can explain why. 我可以解释为什么。 Include persists entity to load all the include objects.So our site object has all references to your clusses (City, Country,User Customer). Includepersistentity实体用于加载所有include对象。因此,我们的站点对象具有对您的线索的所有引用(城市,国家/地区,用户客户)。 I think that is the problem. 我认为这就是问题所在。 The solve can be to load only site object: 解决方法是仅加载站点对象:

Site result = context.Sites.SingleOrDefault(s => s.ID == siteID);

so it would load only ids of the site object. 因此它将仅加载站点对象的ID。 Than you can load refered objects by it ids in runtime where you need. 比您可以在需要的运行时中通过其ID加载引用的对象。

I think it is because when you use include, you operate objects and collections of objects dbContext tracks this changes and saves them when you call 我认为这是因为使用include时,您会操作对象和对象集合dbContext会跟踪此更改并在您调用时保存它们

context.SaveChanges();

a bit refactored code 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
    }
  }

Comment answer Slauma if i don't set it to null, i won't be able to attach them in the update method, the same error would be triggered 评论答案 Slauma如果我不将其设置为null,我将无法在更新方法中附加它们,则将触发相同的错误

Answer: Because when you include all entities you have got already attached to your context objects. 答:因为当包含所有实体时,您已经附加到上下文对象。 Btw Include transforms on sql inner join statement so may be your snapshot of db objects doesnt contain City with that ID. Btw在sql内部连接语句上包含转换,因此可能是您的db对象快照不包含具有该ID的City。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM