2014-02-09 79 views
0

編輯這篇文章缺乏足夠的信息來獲得一些指導嗎?EF上下文在添加實體後不保留值

我有這樣的方法來插入一個實體到數據庫:

public void Insert(T entity) 
{ 
    _context.Set<T>().Add(entity); 
    _context.SaveChanges(); 
} 

當我將它添加到上下文之前檢查entity,我CustomerRole領域是存在的。一旦添加發生,上下文似乎沒有它。正因爲如此,我收到此錯誤:

Entities in 'CcDataContext.Customers' participate in the 'Customer_CustomerRole' relationship. 0 related 'Customer_CustomerRole_Target' were found. 1 'Customer_CustomerRole_Target' is expected.

這些圖像顯示了我的意思:

檢查我的實體 enter image description here

檢查上下文 enter image description here

任何人都可以解釋這種行爲,我能做些什麼?

這是我的類的結構(上剪下來的簡潔):

public class Customer : BaseEntity 
{ 
    public CustomerRole CustomerRole { get; set; } 
} 

class CustomerMap : EntityTypeConfiguration<Customer> 
{ 
    public CustomerMap() 
    { 
     HasRequired(t => t.CustomerRole) 
      .WithMany(t => t.Customers); 
    } 
} 

public class CustomerRole : BaseEntity 
{ 
    private ICollection<Customer> _customers; 
    public ICollection<Customer> Customers 
    { 
     get { return _customers ?? (new List<Customer>()); } 
     set { _customers = value; } 
    } 
} 

我可以證實,客戶地圖被添加到配置和我的數據庫是建立在他們行。

這是我在做這做插入電話:

public Customer InsertGuestCustomer() 
    { 
     var customer = new Customer(); 
     CustomerRole guestRole = GetCustomerRoleByName("Guest"); 
     if (guestRole == null) 
      throw new Exception("Customer Role is not defined!"); 
     customer.UserName = ""; 
     customer.EmailAddress = ""; 
     customer.Password = ""; 
     customer.IsAdmin = false; 
     customer.CustomerRole = guestRole; 
     _customerRepository.Insert(customer); 
     return customer; 
    } 

我在我的數據庫中沒有其他數據,這將是第一個客戶記錄,只有一個CustomerRole。我的Customer表有一個外鍵指向我的CustomerRole.Id表/列。

+1

'Customer' +'CustomerRole'的來源是什麼?他們是如何創建的?預期的行爲是'CustomerRole'具有'Added'狀態。不知怎的,關係修復決定了這種關係應該被打破,但很難說出爲什麼不知道爲什麼不知道在這個「插入」調用之前發生了什麼。也許有原始的外鍵屬性有衝突的值? –

+0

@GertArnold - 感謝您的評論,謝謝。我在圖片下方添加了更多信息。我感謝你的時間。 – webnoob

+0

看着你的代碼,我懷疑'guestRole'被連接到不同於'_customerRepository'中的上下文的上下文中。您必須(以某種方式)在保存更改之前確保它已附加到客戶的上下文(狀態:附加)。或者在'Customer'中設置一個原始的RoleId值。 –

回答

1

將導航屬性標記爲virtual並在實體構造函數中初始化集合屬性,而不是從屬性getter中初始化集合屬性。

public class Customer : BaseEntity 
{ 
    public virtual CustomerRole CustomerRole { get; set; } 
} 

... 

public class CustomerRole : BaseEntity 
{ 
    public CustomerRole() 
    { 
     Customers = new List<Customer>(); 
    } 

    public virtual ICollection<Customer> Customers { get; protected set; } 
} 

在你的客戶的財產,你正在返回的吸氣新的列表時支持字段爲空,但你永遠不分配給你的支持字段。

+0

非常好,你的編輯版本將它整理出來。非常感謝您的時間。我認爲我的結局一定是有點奇怪的(試圖讓它看起來很聰明)。 – webnoob

+0

只檢查了其他正在工作的區域,這可以解釋它。它們是這樣寫的:'get {return _rolePermissions? (_rolePermissions =新列表()); }(注意var賦值)。嘆。漫長的一天。 – webnoob

+0

我從來沒有見過一個公共設置者或收集屬性上的私人支持字段提供任何好處的情況。如果你將setter聲明爲受保護的,並在構造過程中初始化它,這允許你完全操作集合(使用Clear,Add,Remove等),允許動態代理在需要時設置值,並且可以信任值永遠不會爲空。 – danludwig

相關問題