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
Entity framework 为什么实体框架需要ICollection进行延迟加载?_Entity Framework_Domain Driven Design_Lazy Loading - Fatal编程技术网

Entity framework 为什么实体框架需要ICollection进行延迟加载?

Entity framework 为什么实体框架需要ICollection进行延迟加载?,entity-framework,domain-driven-design,lazy-loading,Entity Framework,Domain Driven Design,Lazy Loading,我想写一个丰富的域类,比如 public class Product { public IEnumerable<Photo> Photos {get; private set;} public void AddPhoto(){...} public void RemovePhoto(){...} } 公共类产品 { 公共IEnumerable照片{get;private set;} public void AddPhoto

我想写一个丰富的域类,比如

public class Product    
{    
   public IEnumerable<Photo> Photos {get; private set;}    
   public void AddPhoto(){...}    
   public void RemovePhoto(){...}
 }
公共类产品
{    
公共IEnumerable照片{get;private set;}
public void AddPhoto(){…}
public void RemovePhoto(){…}
}
但是实体框架(V4代码优先方法)需要一个ICollection类型来延迟加载!由于客户端可以绕过AddPhoto/RemovePhoto方法,直接在ICollection上调用add方法,因此上述代码不再按设计工作。这不好

public class Product    
{    
   public ICollection<Photo> Photos {get; private set;} //Bad    
   public void AddPhoto(){...}    
   public void RemovePhoto(){...}    
 }
公共类产品
{    
公共i收集照片{get;private set;}//错误
public void AddPhoto(){…}
public void RemovePhoto(){…}
}
试图用EF4实现DDD真的令人沮丧。为什么他们选择ICollection进行延迟加载


我怎样才能克服这个问题?NHibernate是否为我提供了更好的DDD体验?

您不能插入IEnumerable。这适用于EF,就像它适用于您的客户一样。不过,您不必使用ICollection;您可以使用IList或其他可写类型。我的建议是将DTO而非实体公开给您的客户。我想我找到了解决方案……有关更多详细信息,请参阅此处:

实际上,您希望保护ICollection类型,并将其用作公共IEnumerable的支持集合

public class Product
{

   // This is a mapped property
   protected virtual ICollection<Photo> _photos { get; set; }

   // This is an un-mapped property that just wraps _photos
   public IEnumerable<Photo> Photos
   {
      get  { return _photos; }
   }

   public void AddPhoto(){...}
   public void RemovePhoto(){...}

} 
公共类产品
{
//这是一个映射属性
受保护的虚拟ICollection\u照片{get;set;}
//这是一个仅包装照片的未映射属性
公共数字照片
{
获取{return\u photos;}
}
public void AddPhoto(){…}
public void RemovePhoto(){…}
} 

要使延迟加载工作,类型必须实现ICollection,并且访问必须是公共的或受保护的。

您可以通过使用

公共类产品
{  
私人IList_照片;
公众照片{
得到
{
返回_photos.AsReadOnly();
}
私有集{u photos=value;}
}
public void AddPhoto(){…}
public void RemovePhoto(){…}
}
编辑:
ICollection
=>
IList


希望这就是你想要的。

真的。公开DTO并根据这些DTO生成视图模型是我选择的路径。我想有太多的人会被吓跑,但听起来他们需要编写多少代码才能完成。我知道这是一篇老文章,但你能详细说明一下这个答案吗?@Rushino:你的公共界面是一份合同。如果第三方与它集成,它是不变的,您无法更改它。但是你可能想进化你的数据库,对吗?您的EF模型主要与DB匹配,因此您也需要对其进行改进。因此,使用单一责任原则:使用一种类型DTO来定义公共接口。使用另一种类型(实体)来处理DB映射到可以/可能更改的架构。您有示例吗?我很直观,我相信这会帮助其他人。@Rushino:仅供参考,NHibernate要求你使用IList,它实现了ICollection,所以你必须对NHibernate使用同样的技巧。这是这个答案的解决方案吗?你赢得了赏金。:)享受吧!hazzik也一样。如果您使用存储库或只是尝试编写一个LINQ表达式,该表达式将由EF转换为SQL语句,并尝试使用公共IEnumerable,它不起作用……该属性未映射,LINQ to Entities不支持该属性。@Kevin-IEnumerable与NHibernate配合使用效果良好,集合可以映射到私有支持字段以获得所需的结果。查询违背了公众IEnmerable{get}试图自己解决这个问题。我知道要走的路就是你描述的路。但是怎么做呢?现在在EF 4.1中也可以吗?还是你找到了解决办法?
public class Product    
{  
    private IList<Photo> _photos;  
    public IList<Photo> Photos {
        get
        {
            return _photos.AsReadOnly();
        }
        private set { _photos = value; }
    }
    public void AddPhoto(){...}    
    public void RemovePhoto(){...}    
}