5

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

内部访问已在图表(.edmx 文件)中设置,并且在我用作库内的工厂的静态类中,我有如下内容:

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

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

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

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

有什么建议么?

4

2 回答 2

5

更新!实际上找到了一个更直接的解决这个问题的方法:

  1. 在设计器中打开 edmx
  2. 将“实体容器访问”设置为内部
  3. 确保所有实体都将“访问”设置为公开
  4. 展开 edmx 并编辑实体 t4(不是 *.Context.tt)
  5. 在 t4 中搜索Accessibility.ForType(entity)并将其替换为"Internal"(或"Friend"用于 VB)
  6. 保存/重新运行 T4 就可以了。

遵循这些步骤后,您的 EF 项目的任何部分都不应在程序集之外可见,并且一切都应该“正常工作”。

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




这已经在这里得到了回答:c# DbSet - Internal object cannot be got

要点是,如果您将实体集/数据库集属性设置为内部属性,它将不会被 EF 自动实例化。但是您可以按照该页面上接受的答案中的描述手动实例化它。




另一个需要注意的问题:

VS2012 中存在一个错误(版本 11.0.60610.01 更新 3 是我当前的环境),即使它报告好像确实如此,设计师也不会在基础 edmx 文件中正确地将项目设置回公共。

因此,即使将项目设置回公共,重新运行上下文 t4 并重建,您仍然会收到该异常。

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

于 2013-08-29T01:44:39.083 回答
0

另一个命名空间中的代码如何设置命名空间中对象的属性?如果您考虑 EF 如何与您的代码位于不同的命名空间中,但在其中填充属性,我敢说这public有点必要。

于 2012-12-19T10:52:38.523 回答