2017-03-27 159 views
1

我首先在代碼中使用實體框架。我的關係屬性繼續打破。實體框架導航屬性null

我有對象Element

public class Element : IElement 
{ 
    // ... some event handlers (removed) 

    [Key] 
    public Guid ID { get; set; } = Guid.NewGuid(); 

    public string Name { get; set; } 

    // navigation properties 
    public virtual ElementType ElementType { get; private set; } 

    public virtual NotifiableCollection<Property> Properties { get; private set; } = new NotifiableCollection<Property>(); 

    // Parameterless constructor for serialization 
    private Element() { } 

    public Element(ElementType elementType) : base() 
    { 
     // loop through and create Properties for each Property Type 
     ElementType = elementType; 
     if (ElementType?.PropertyTypes != null) 
     { 
      ElementType.PropertyTypes.ToList().ForEach((property) => 
      { 
       Properties.Add(new Property(property)); 
      }); 
     } 
    } 
} 

而且ElementType

public class ElementType : IElementType 
{ 
    // ... some event handlers (removed) 

    [Key] 
    public Guid ID { get; set; } = Guid.NewGuid(); 

    public string Name { get; set; } 

    // navigation properties 
    public virtual NotifiableCollection<PropertyType> PropertyTypes { get; set; } = new NotifiableCollection<PropertyType>(); 

    public virtual NotifiableCollection<Element> Elements { get; set; } = new NotifiableCollection<Element>(); 

    public ElementType() 
    { 
     // ensure our Element's get updates 
     PropertyTypes.CollectionChanged += (e, a) => 
     { 
      //update the database to send out renewal to interested entities 
      if (a.ChangeType == ChangeType.Added) 
      { 
       foreach (Element element in Elements) 
       { 
        element.Properties.Add(new Property(a.Item)); 
       } 
      } 
     }; 
    } 
} 

當我創建這些對象的第一次(因爲我已經明確設置導航屬性,然後保存它工作正常):

enter image description here

然而,當我再關閉一切,並從數據庫中獲取這些:

enter image description here

的導航屬性都沒有解決。該表定義建立foregn鍵關係罰款:

CREATE TABLE [dbo].[Elements] (
    [ID]    UNIQUEIDENTIFIER NOT NULL, 
    [Name]   NVARCHAR (MAX) NULL, 
    [ElementType_ID] UNIQUEIDENTIFIER NULL, 
    CONSTRAINT [PK_dbo.Elements] PRIMARY KEY CLUSTERED ([ID] ASC), 
    CONSTRAINT [FK_dbo.Elements_dbo.ElementTypes_ElementType_ID] FOREIGN KEY ([ElementType_ID]) REFERENCES [dbo].[ElementTypes] ([ID]) 
); 


GO 
CREATE NONCLUSTERED INDEX [IX_ElementType_ID] 
    ON [dbo].[Elements]([ElementType_ID] ASC); 

,我可以看到的數據是正確的:

ID         Name        ElementType_ID 
ff186746-62cb-4246-9c64-f2d007b23ac0 Aircon Test 27/03/2017 12:54:03 57d93ac1-ad3b-4718-a593-80639cc24907 
其匹配的ElementType表中的ID

我有這一套在我的倉庫:

context.Configuration.ProxyCreationEnabled = true; 
context.Configuration.LazyLoadingEnabled = true; 

和上下文仍然活躍在那裏我試圖解決這個屬性的時間。

一切正常,但我已經與EF多次這個問題,我的導航屬性只是隨機突破。我不記得觸及任何與此元素相關的代碼,只是運行它,現在它不起作用。誰能幫忙?

編輯:這是庫代碼:

public sealed class Repository : IRepository 
{ 
    public event ObjectMaterializedEventHandler ObjectMaterialized; 

    public Repository() { 
     (context as IObjectContextAdapter).ObjectContext.ObjectMaterialized += ObjectContext_ObjectMaterialized; ; 
     context.Configuration.ProxyCreationEnabled = true; 
     context.Configuration.LazyLoadingEnabled = true; 
    } 

    // I do this to wire in some events later 
    private void ObjectContext_ObjectMaterialized(object sender, ObjectMaterializedEventArgs e) 
    { 
     ObjectMaterialized?.Invoke(this, e); 
    } 

    private DataContext context = new DataContext(false); 

    public IEnumerable<T> GetAll<T>() where T : class 
    { 
     return context.Set<T>().ToList() as IEnumerable<T>; 
    } 

    public T GetItem<T>(Guid id) where T : class 
    { 
     return context.Set<T>().Find(id) as T; 
    } 
    ... 
} 

的情況下將它們存儲這樣的:

public class DataContext : DbContext 
{ 
    ... 
    public DbSet<Element> Elements { get; set; } 
    public DbSet<ElementType> ElementTypes { get; set; } 
} 

我認爲這是值得做的訪問。我正在使用context.Set()來訪問元素,發現(id)爲T,並且失敗。但是,如果我通過ElementTypes進行navagate,找到它的實體列表,那麼它工作正常。

+0

您是否重複使用您的EF上下文進行多項操作(即:是否將它保存在某個靜態\實例變量中)? – Evk

+0

你能展示如何從數據庫獲取實體嗎?你是否在「使用」塊中封裝了上下文/存儲庫? – DavidG

+0

是的,上下文保留在存儲庫中。我將添加一些代碼來顯示檢索。 – Joe

回答

3

在Ivan的幫助下在評論中找到了答案。

的問題是與具有私有構造函數:

// Parameterless constructor for serialization 
private Element() { } 

一個爲proxies的要求是一個公共或受保護的構造:

對於這兩種代理要創建:自定義數據類別必須爲 ,並聲明爲公共訪問權限。

  • 自定義數據類必須不(在Visual 基本NotInheritable)被密封

  • 自定義數據類不能是抽象的(爲MustInherit在Visual 基本)。

  • 自定義數據類必須有一個公共或受保護的構造是 沒有參數。如果您希望使用CreateObject方法爲POCO實體創建 代理,請使用不帶 參數的受保護構造函數。調用CreateObject方法不保證創建代理服務器:POCO類必須遵循本主題中描述的其他要求 。

  • 該類無法實現IEntityWithChangeTracker或 IEntityWithRelationships接口,因爲代理類 實現了這些接口。

  • ProxyCreationEnabled選項必須設置爲true。

對於延遲加載代理:每個導航屬性必須聲明爲 公開,虛擬(可重寫在Visual Basic),以及(在Visual Basic NotOverridable)不密封 get訪問。