Entity framework 先使用实体框架4.1代码的复合模式
我首先需要用实体框架代码表示一个复合模式。如何做到这一点? 我读过一篇关于使用访问者模式的帖子,但我认为使用fluentapi应该很容易做到,也不太复杂,但我不知道怎么做 它将数据正确地保存在数据库中,但当我尝试再次加载它时,它会带来错误的数据Entity framework 先使用实体框架4.1代码的复合模式,entity-framework,entity-framework-4.1,ef-code-first,code-first,Entity Framework,Entity Framework 4.1,Ef Code First,Code First,我首先需要用实体框架代码表示一个复合模式。如何做到这一点? 我读过一篇关于使用访问者模式的帖子,但我认为使用fluentapi应该很容易做到,也不太复杂,但我不知道怎么做 它将数据正确地保存在数据库中,但当我尝试再次加载它时,它会带来错误的数据 var components = from p in ctx.LayerComponents.Include("ComponentsLayer").Include("Component") select p; foreach (var p in com
var components = from p in ctx.LayerComponents.Include("ComponentsLayer").Include("Component") select p;
foreach (var p in components)
{
Trace.WriteLine("------------------------------------------------------------------------------------------------");
p.Apply();
}
这是我目前的模型:
public abstract class LayerComponents
{
public LayerComponents()
{
Components = new List<Component>();
}
[Key]
public int Id { get; set; }
public string Description { get; set; }
public ICollection<Component> Components { get; set; }
public abstract void Apply();
public abstract void AddLayer(LayerComponents component);
public abstract void RemoveLayer(LayerComponents component);
public abstract void AddComponent(Component component);
}
public class CompositeLayerComponents : LayerComponents
{
public ICollection<LayerComponents> ComponentsLayer { get; set; }
public int? ParentID { get; set; }
public CompositeLayerComponents Parent { get; set; }
public CompositeLayerComponents()
{
ComponentsLayer = new List<LayerComponents>();
}
public override void ApplyComponents()
{
foreach (LayerComponents lp in ComponentsLayer)
{
lp.ApplyComponents();
}
Trace.WriteLine("Inside: " + Description);
foreach (var p in Components)
{
Trace.WriteLine(" Applying component: " + p.Key.ToString() + "-" + p.Value.ToString());
}
Trace.WriteLine("Done Applying Components in " + Description + Environment.NewLine);
}
public override void AddLayer(LayerComponents component)
{
ComponentsLayer.Add(component);
}
public override void RemoveLayer(LayerComponents component)
{
ComponentsLayer.Remove(component);
}
public override void AddComponent(Component component)
{
this.Components.Add(component);
}
}
public class LeafLayerComponents : LayerComponents
{
public override void ApplyComponents()
{
Trace.WriteLine("Inside: " + Description);
foreach (var p in Components)
{
Trace.WriteLine(" Applying component: " + p.Key.ToString() + "-" + p.Value.ToString());
}
Trace.WriteLine("Done Applying Components in " + Description + Environment.NewLine);
}
public override void AddLayer(LayerComponents component)
{
throw new Exception("Can't add a layer to the LeafLayerComponents");
}
public override void RemoveLayer(LayerComponents component)
{
throw new Exception("Can't add a layer to the LeafLayerComponents");
}
public override void AddComponent(Component component)
{
Components.Add(component);
}
}
public class Component
{
[Key]
public int Id { get; set; }
[Required]
protected string Description { get; set; }
[Required]
public int KeyValue { get; set; }
[Required]
public string Value { get; set; }
[Required]
public Guid userId { get; set; }
}
它不会加载一个根层,其中一个buildingLayerComponent内部有两个FloorLayerComponent,其中一个FloorLayerComponent有一个officeLayerComponent。这就是问题所在,如何重新加载该层次结构。很难遵循您的代码,因为它甚至不可编译,但如果您的问题是它没有加载整个层次结构,那么这不是问题,它是一个功能。EF不会自动加载关系。你必须告诉它去做,在层次结构中,这实际上是非常困难的 您可以使用即时加载:
var root = context.LayerComponents.OfType<CompositeLayerComponsnts>().Include(c => c.ComponentsLayer).Where(c => c.ParentId == null);
var root=context.LayerComponents.OfType().Include(c=>c.ComponentsLayer)。其中(c=>c.ParentId==null);
此查询将加载所有顶级复合材料及其直接层组件(仅单个级别!)
您也可以使用延迟加载,但必须将所有导航属性标记为virtual
。在这种情况下,一旦第一次访问,EF将创建单独的查询来加载每个导航属性。在层次结构中,这可能导致大量数据库查询
我预计您的代码将有许多其他问题。例如,如果您希望所有三个层都使用相同的组件,则它们不会使用相同的组件-每个组件将被添加三次,并且如果键表示其主键,则它将具有不同的值
在开始进行复杂的映射之前,您可能应该先了解一下EF及其工作原理,否则您会遇到很多麻烦。问题是什么?映射为TPH的模型似乎是正确的。它表示“System.Linq.IQueryable”不包含“Include”的定义,并且找不到扩展方法“Include”接受类型为“System.Linq.IQueryable”的第一个参数(是否缺少using指令或程序集引用?)可能有什么问题?您确定使用的是EFv4.1吗?您的代码中是否有使用System.Data.Entity的
?您是否建议使用实体框架实现复合模式的“最佳实践”?我不这么认为,因为这应该是可行的。无论如何,派生类上的关系是有问题的,您可以期待它们会有更多的问题。复合和实体框架是两个独立的领域。实体框架用于将实体映射到数据库,并且并不是所有可以在应用程序中构建的内容都可以轻松映射到数据库中。每次使用分层结构时,我都会使用直接SQL/存储过程,这仅仅是因为性能。
var root = context.LayerComponents.OfType<CompositeLayerComponsnts>().Include(c => c.ComponentsLayer).Where(c => c.ParentId == null);