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 - Fatal编程技术网

C# 实体框架代理创建

C# 实体框架代理创建,c#,entity-framework,C#,Entity Framework,我见过不少解决问题的方法,这些方法总是和我的类似。但没有一个能特别满足我的需求 我有以下设置: public class User { public Int32 Id { get; set; } public String Name { get; set; } public virtual List<PhoneBook> Phonebooks { get; set; } } public class PhoneBook { public Int32

我见过不少解决问题的方法,这些方法总是和我的类似。但没有一个能特别满足我的需求

我有以下设置:

public class User
{
    public Int32 Id { get; set; }
    public String Name { get; set; }
    public virtual List<PhoneBook> Phonebooks { get; set; }
}

public class PhoneBook
{
    public Int32 Id { get; set; }
    public virtual Int32 UserId { get; set; }
    public virtual User User { get; set; }
    public String Title { get; set; }
    public virtual List<PhoneNumber> Number { get; set; }
}

public class PhoneNumber
{
    public Int32 Id { get; set; }
    public String Num { get; set; }
    public virtual Int32 PhoneBookId { get; set; }
    public virtual PhoneBook PhoneBook { get; set; }
}
公共类用户
{
公共Int32 Id{get;set;}
公共字符串名称{get;set;}
公共虚拟列表电话簿{get;set;}
}
公共类电话簿
{
公共Int32 Id{get;set;}
公共虚拟Int32用户标识{get;set;}
公共虚拟用户用户{get;set;}
公共字符串标题{get;set;}
公共虚拟列表编号{get;set;}
}
公共类电话号码
{
公共Int32 Id{get;set;}
公共字符串Num{get;set;}
公共虚拟Int32 PhoneBookId{get;set;}
公共虚拟电话簿电话簿{get;set;}
}
现在我完全可以提问了。问题在于循环引用

假设我想为id=1的用户选择每个电话簿 我的问题是
context.phonebook.Where(x=>x.UserId==1)
这将加载用户和每个电话号码。 我可以关闭代理,我只能得到电话簿(没有号码,没有用户)

如果我也想获取每个电话号码,但不想获取用户,该怎么办? 此外,我还必须确保获取phonenumber对象并不意味着获取与该号码相关的电话簿。
我需要代理只走一条路。向下而不是向上。

首先,您的外键ID不需要是虚拟的。只能对导航属性(或其他实体类型属性)使用
virtual
:外键不是导航属性,它只是一个整数

现在,您的问题实际上与代理无关,而是与延迟加载有关(代理默认启用延迟加载,这就是您关心代理的原因,但这不是必需的)

如果只想加载指定的实体,请禁用延迟加载并执行快速加载:

context.Configuration.LazyLoadingEnabled = false;

// Load phonebook entries and users matching your id
var result = content.phonebook
                .Include(x => x.Number)
                .Include(x => x.User)
                .Where(x => x.UserId == 1); 

// Load only phonebook entries without users    
var result2 = content.phonebook
                .Include(x => x.Number)
                .Where(x => x.UserId == 1); 
这么简单


PS:代理比延迟加载(如更改跟踪等)更有优势。如果您的问题是延迟加载,请关闭延迟加载,而不是代理。

在这种情况下,造成痛苦的不是代理创建,而是延迟加载禁用它,并包括您想要的导航属性,或专门投影您的结果:

context.phonebook
  .Include(x=> x.Number)
  .Where(x=>x.UserId == 1);
// or
context.phonebook
  .Where(x=>x.UserId == 1)
  .Select(x=> new{ 
       Phonebook = x,
       Number = x.Number
       });

加载相关数据的三种方法:@MarianneMarkwardt不,你不是。外键只是整数。导航属性指向其他实体。它们会自动填充外部实体id,但这不是“导航属性”。要加载另一个级别,可以使用字符串语法(
.Include(“Number.OtherLevel”)
,或者lambda语法:对于导航属性:
Include(s=>s.Number.OtherProperty)
,或者对于集合:
Include(s=>s.Number.Select(t=>t.CollectionItem))
。这里介绍了所有内容:(查找“急切地加载多个级别”)好的。非常感谢Jcl。我标记了你的答案。虽然这个问题可能属于另一个主题,但你能告诉我为什么context.phonebooks.Where(x=>x.id==1)可以工作,但是context.phonebooks.Include(x=>x.title)由于错误而失败”指定的包含路径无效。EntityType..未声明名为“Title”的导航属性。“Include”用于加载相关实体。“Title”是字符串类型的属性,而不是相关实体(导航属性或集合)是..我刚按enter键时意识到这一点..再次感谢Jcl。祝您愉快:)