2015-10-04 78 views
0

我有兩個模型與一對多關係,如果我保存在不同的實例DbContext,這會拋出一個異常(違反主鍵) - 如何避免它?實體框架違反主鍵約束6,模型一對多

public class Customer 
{ 
    public Guid Id { get; set; } 
    public string Name { get; set; } 
} 

public class User 
{ 
    public Guid Id { get; set; } 
    public string Name { get; set; } 
    public Customer Customer { get; set; } 
} 

public class DbContext : System.Data.Entity.DbContext 
{ 
    public DbContext() 
    : base(@"Data Source=(localdb)\MSSQLLocalDB; AttachDBFilename='|DataDirectory|\Sample.mdf'; Integrated Security=True") 
    { 
     Configuration.ProxyCreationEnabled = false; 
     Configuration.AutoDetectChangesEnabled = true; 
     Configuration.ValidateOnSaveEnabled = true; 
     Configuration.LazyLoadingEnabled = true; 
    } 

    public IDbSet<Customer> Customers { get; set; } 
    public IDbSet<User> Users { get; set; } 

    protected override void OnModelCreating(DbModelBuilder modelBuilder) 
    { 
     modelBuilder.Properties<Guid>() 
     .Where(p => p.Name == "Id") 
     .Configure(p => { p.IsKey(); p.IsRequired(); }); 
    } 
} 

AppDomain.CurrentDomain.SetData(
    "DataDirectory", 
    System.Environment.CurrentDirectory); 

var customer = new Customer(); 
customer.Id = Guid.NewGuid(); 
customer.Name = "customername"; 

using (var db = new DbContext()) 
{ 
    db.Customers.Add(customer); 
    db.SaveChanges(); 
} 

var user = new User(); 
user.Id = Guid.NewGuid(); 
user.Name = "username"; 
user.Customer = customer; 

using (var db = new DbContext()) 
{ 
    db.Users.Add(user); 
    db.SaveChanges(); // <- Throw here 
} 
當然

這是一個簡化的樣品,在寫什麼,可以使用DbContext只有一個實例,但在現實中客戶作爲參數傳遞給方法

回答

1

你是正確的 - 第二個實例不會知道你剛剛添加了客戶。無論是包裝他們在同一個using語句或者你可以告訴客戶已經存在的第二個實例:

var user = new User(); 
user.Id = Guid.NewGuid(); 
user.Name = "username"; 

using (var db = new DbContext()) 
{ 
    user.Customer = new Customer() { Id = customer.Id }; // only need the id 
    db.Customers.Attach(user.Customer); 
    db.Users.Add(user); 
    db.SaveChanges(); 
} 

Entity Framework: adding existing child POCO to new Parent POCO, creates new child in DB

+1

的*存根*('新客戶(){ID = customer.Id}')在這裏沒有必要,因爲'客戶'也可以被附加。但確實是爲了防止從數據庫中提取「客戶」而推薦的方法。 –

+0

顯然,我給出了一個不好的例子,我們會說客戶已經在數據庫中,如果它沒有加載到更新用戶的dbcontext中,entityframework試圖創建一個新的客戶,當然它崩潰。 – mchouteau