Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/entity-framework/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 实体框架。。如何映射自引用外键。。类别有很多类别_C#_Entity Framework_Poco - Fatal编程技术网

C# 实体框架。。如何映射自引用外键。。类别有很多类别

C# 实体框架。。如何映射自引用外键。。类别有很多类别,c#,entity-framework,poco,C#,Entity Framework,Poco,我有以下poco课程: public class Category : IDisplayName { private ICollection<Category> children; private Category parent; public Category() { children = new List<Category>(); } public int Id { get; set; }

我有以下poco课程:

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; }
    }
}
公共类类别:IDisplayName
{
私人收集儿童;
私人类别家长;
公共类别()
{
children=新列表();
}
公共int Id{get;set;}
公共字符串名称{get;set;}
公共虚拟类别父级
{
获取{return parent;}
设置
{
父=值;
//if(value!=null&&parent.Children.Contains(this)==false)
// {
//parent.Children.Add(此);
// }
}
}
公共虚拟ICollection子对象
{
获取{返回子项;}
设置{children=value;}
}
}
这是映射文件(我不确定这是否正确..但我没有想法,所有文档都有问题…)

公共类类别实体配置:实体配置
{
公共类别实体配置()
{
属性(x=>x.Name).IsRequired();
有许多(x=>x.Children)。带有可选(x=>x.Parent);
has可选(x=>x.Parent)。具有多个(x=>x.Children);
}
}
请注意“Parent”属性以及我如何不使用“Children”集合分别添加它们

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);
var cat_0=新类别{Name=“Root”};
var cat_1=新类别{Name=“Property”,Parent=cat_0};
var cat_2=新类别{Name=“财产服务”,父类=cat_1};
var cat_3=新类别{Name=“住房协会”,父类=cat_2};
var cat_4=新类别{Name=“抵押与转让”,父类=cat_2};
var cat_5=新类别{Name=“财产管理”,父类=cat_2};
var cat_6=新类别{Name=“财产拍卖”,父类=cat_2};
var cat_7=新类别{Name=“需要房东”,Parent=cat_2};
context.Set().Add(cat_0);
当我将cat_0保存到数据库时,只插入了一行,实体框架没有发现cat_0是一大堆其他对象的父对象,也没有意识到它们需要被持久化。我有一个变通方法,就是在“父”类别属性中注释掉的代码。。但我宁愿不这样做,因为我觉得这样做不对

任何帮助都将不胜感激


杰克

这是可能的,但你必须使用跟踪代理。为此,请修改您的Category类,以便所有持久化属性都是虚拟的

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; } 
} 
公共类类别
{ 
公共虚拟整数Id{get;set;}
公共虚拟字符串名称{get;set;}
公共虚拟类别父项{get;set;}
公共虚拟ICollection子项{get;set;}
} 
创建上下文并检查是否允许创建动态代理。在这样的上下文中,您可以使用CreateObject方法来获取类别实例。您将不会获得Category类型的实例,而是从Category继承的动态类型。此动态代理负责延迟加载(如果启用)和对现有上下文的更改跟踪。如果修改一侧的导航属性,它将自动修改另一侧的导航属性

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(); 
}
使用(var context=newobjectcontext(connectionString))
{
//这应该是默认值
context.ContextOptions.ProxyCreationEnabled=true;
var cat0=context.CreateObject();
cat0.Name=“A”;
var cat1=context.CreateObject();
cat1.Name=“B”;
cat1。父项=cat0;
context.CreateObjectSet().AddObject(cat0);
SaveChanges();
}
编辑:


如果您不喜欢跟踪代理(需要现有上下文)的方法,您可以反转创建实体的方式。您不必在child上设置Parent属性,而必须在Parent上填充child。在这种情况下,它会起作用。

是的,谢谢你的回答是的,我猜ObjectContext在创建时必须知道实体。此外,我正在使用DbContext类,该类将ObjectContext作为受保护的属性,不确定隐藏ObjectContext公开的所有功能背后的原因。希望听到有关原因的任何反馈:)
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(); 
}