【发布时间】:2017-03-27 12:03:46
【问题描述】:
我首先使用实体框架和代码。我的关系属性不断中断。
我有对象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));
}
}
};
}
}
当我第一次创建这些对象时它工作正常(因为我已明确设置导航属性然后保存):
但是,当我关闭所有内容并从数据库中获取这些内容时:
导航属性未解析。表定义很好地设置了外键关系:
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().Find(id) 作为 T 访问元素,但它失败了。但是,如果我浏览 ElementTypes,找到它的实体列表,那么它工作正常。
【问题讨论】:
-
您是否将 EF 上下文重用于多个操作(即:您是否将其保存在某个静态\实例变量中)?
-
您能否展示一下如何从数据库中获取实体?您是否将上下文/存储库包装在
using块中? -
是的,上下文保留在存储库中。我将从这里添加一些代码来显示检索。
-
在尝试枚举导航属性之前存储库是否已销毁?
-
` as T` 无法更改实际类型。看起来
Find没有返回代理。因此,要么 (A) 出于某种原因Element不符合延迟加载到 EF 的条件,要么 (B) 您手动添加了Element实例。如果你下断点并尝试context.Set<Element>().Create();,它是否返回代理(消除大小写(B))?
标签: c# entity-framework