4

//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 が競合しているようです。誰かが理由を説明できますか?または任意の回避策?

4

1 に答える 1

2

理由は説明できます。インクルードは、すべてのインクルード オブジェクトをロードするエンティティを永続化します。したがって、サイト オブジェクトには、クラス (都市、国、ユーザー カスタマー) へのすべての参照があります。それが問題だと思います。解決策は、サイト オブジェクトのみをロードすることです。

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

そのため、サイト オブジェクトの ID のみが読み込まれます。必要に応じて、実行時に ID によって参照されたオブジェクトをロードできます。

インクルードを使用すると、オブジェクトとオブジェクトのコレクションを操作するためだと思います dbContext は、この変更を追跡し、呼び出すときにそれらを保存します

context.SaveChanges();

ところで、少しリファクタリングされたコード:

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に設定しないと、更新メソッドでそれらを添付できなくなり、同じエラーが発生します

回答: すべてのエンティティを含めると、コンテキスト オブジェクトに既に関連付けられているためです。ところで、SQLの内部結合ステートメントに変換を含めるため、dbオブジェクトのスナップショットにそのIDのCityが含まれていない可能性があります。

于 2013-10-08T06:42:46.283 に答える