实体框架..我如何映射自我的借鉴外键..如类别有很多分类 [英] Entity Framework.. How do I map a self referencial foreign key.. eg Category has many Categories

查看:181
本文介绍了实体框架..我如何映射自我的借鉴外键..如类别有很多分类的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有以下的POCO类:

I have the following poco class:

public class Category : IDisplayName
{
    private ICollection<Category> children;
    private Category parent;

    public Category()
    {
        children = new List<Category>();
    }

    public int Id { get; set; }

    public string Name { get; set; }

    public virtual Category Parent
    {
        get { return parent; }
        set
        {
            parent = value;

            // if (value != null && parent.Children.Contains(this) == false)
            // {
            //      parent.Children.Add(this);
            // }
        }
    }

    public virtual ICollection<Category> Children
    {
        get { return children; }
        set { children = value; }
    }
}

这是映射文件(我不知道如果这是正确的..但我的想法并没有鸡奸的所有文件在那里...)

This is the Mapping file (I am not sure if this is correct.. but I am out of ideas and there is bugger all documentation out there...)

public class CategoryEntityConfiguration : EntityConfiguration<Category>
{
    public CategoryEntityConfiguration()
    {
        Property(x => x.Name).IsRequired();

        HasMany(x => x.Children).WithOptional(x => x.Parent);
        HasOptional(x => x.Parent).WithMany(x => x.Children);
    }
}



注意父财产,我是多么不,加入他们每人用孩子集合

Notice the "Parent" property and how I am not adding them each using the "Children" collection.

var cat_0 = new Category { Name = "Root" };            
var cat_1 = new Category { Name = "Property", Parent = cat_0 };
var cat_2 = new Category { Name = "Property Services", Parent = cat_1 };
var cat_3 = new Category { Name = "Housing Association", Parent = cat_2 };
var cat_4 = new Category { Name = "Mortgages & Conveyancing", Parent = cat_2 };
var cat_5 = new Category { Name = "Property Management", Parent = cat_2 };
var cat_6 = new Category { Name = "Property Auctions", Parent = cat_2 };
var cat_7 = new Category { Name = "Landlords Wanted", Parent = cat_2 };

context.Set<Category>().Add(cat_0);

在我的cat_0保存到只有1行插入数据库和Entity Framework不拿起其实cat_0是一大堆其他对象的父母没有意识到,他们需要被持久化。我有一个解决方法是在父类别属性注释掉的代码..但我宁愿没有这样做,因为就是感觉不对。

When I save the cat_0 to the database only 1 row is inserted and Entity Framework does not pick up the fact the cat_0 is the parent of a whole bunch of other objects and does not realise that they need to be persisted. I have a workaround which is the commented out code in the "Parent" category property.. but I would rather not have to do this as is does not feel right.

任何帮助将非常感激。

杰克

推荐答案

有可能但你必须使用跟踪代理。要做到这一点修改您的范畴类,这样的所有持续性是虚拟的。

It is possible but you have to use tracking proxies. To do that modify your Category class so that all persisted properties are virtual.

public class Category 
{ 
    public virtual int Id { get; set; } 
    public virtual string Name { get; set; } 
    public virtual Category Parent { get; set; }
    public virtual ICollection<Category> Children { get; set; } 
} 



创建上下文,并检查动态代理的创建是允许的。在这样的背景下,您可以使用CreateObject方法,让您的类的实例。你不会得到类型类别的实例,但动态类型从类别继承。这种动态代理负责懒加载(如果启用)和更改跟踪到现有的环境。如果你在一边修改导航属性会自动修改的另一边导航属性。

Create context and check that creation of dynamic proxy is allowed. On such context you can use CreateObject method to get your category instance. You will not get instance of type Category but dynamic type inherited from Category. This dynamic proxy is responsible for lazy loading (if enabled) and for change tracking to existing context. If you modify navigation property on the one side it will automatically modify navigation property on the other side.

using (var context = new ObjectContext(connectionString))
{
  // This should be default value
  context.ContextOptions.ProxyCreationEnabled = true;

  var cat0 = context.CreateObject<Category>();
  cat0.Name = "A";

  var cat1 = context.CreateObject<Category>();
  cat1.Name = "B";
  cat1.Parent = cat0;

  context.CreateObjectSet<Category>().AddObject(cat0);
  context.SaveChanges(); 
}



编辑:

如果你不喜欢与跟踪代理(这需要对现有上下文)方法,你可以扭转你创建实体的方式。相反,对孩子的家长设置属性你必须填写童车上的父母。在这种情况下,将工作

If you don't like approach with tracking proxies (which require existing context) you can reverse the way you create your entities. Instead of setting Parent property on childs you have to fill Childs on parent. In that case it will work.

这篇关于实体框架..我如何映射自我的借鉴外键..如类别有很多分类的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆