简体   繁体   中英

Foreign key conflict

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

I have 2 tables Customers and 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);

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.

however, adding test.Customer.City = null; before updating the object would work. it seems like Customer.City and Site.City is conflicting. 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). 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. Than you can load refered objects by it ids in runtime where you need.

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

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

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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