实体框架中实体的内部访问使查询崩溃时的linq变得简单



我正在开发一个使用EF进行数据库访问的库。为了避免将实体暴露在库外,我已将所有表的访问权限设置为内部(我还将实体容器访问设置为内部)。现在的问题是,在库中,当我试图通过实体id获取实体时,Where查询会抛出异常,我不知道为什么。

内部访问已经在图表(.edmx文件)中设置,在我用作库内工厂的静态类中,我有这样的东西:

var id = 1234;
var mec = new MyEntitiesContainer();
var myEntity = mec.MyEntities.Where(e => e.MyEntitiesId == id).FirstOrDefault();

通过id从数据库中获取具体实体(行)的简单where查询。

当所有实体类访问都是公共的时,没有问题,但当我将它们设置为内部时,会抛出此异常:

System.ArgumentNullException: Value cannot be null.  Parameter name: source     
at System.Linq.Queryable.Where[TSource](IQueryable`1 source, Expression`1 predicate)

有什么建议吗?

更新实际上找到了一个更直接的解决方案:

  1. 在设计器中打开edmx
  2. 将"实体容器访问"设置为内部
  3. 确保所有实体的"访问权限"都设置为"公共">
  4. 展开edmx并编辑实体t4(不是*.Context.tt)
  5. 在t4中,搜索Accessibility.ForType(entity)并将其替换为"Internal"(或为VB搜索"Friend")
  6. 保存/重新运行T4,仅此而已

遵循这些步骤后,您的EF项目的任何部分都不应在大会外可见,一切都应"正常工作"。

如果您仍然遇到"Value cannot be null"异常,请参阅本文底部的"gotcha"。




这里已经回答了这个问题:c#DbSet-内部对象无法获得

要点是,如果将entityset/dbset属性设置为内部,则EF不会自动实例化它。但您可以手动实例化它,如该页面上已接受的答案中所述。




另一个需要注意的问题:

VS2012中有一个错误(11.0.60610.01更新3是我当前的环境),设计器不会正确地将基础edmx文件中的项设置回Public,即使它报告的情况是这样的。

因此,即使在将项设置回public、重新运行上下文t4并重新构建之后,您仍然会收到该异常。

我找到的唯一解决方法是打开edmx文件并手动编辑它,将内部设置回public。

来自另一个命名空间的代码如何设置命名空间中对象的属性?如果您想一想EF是如何生活在与代码不同的名称空间中,并在其中填充属性的,我敢说public在某种程度上是必要的。

相关内容

最新更新