【问题标题】:Entity Framework DBContext navigation property loaded by different query?不同查询加载的实体框架 DBContext 导航属性?
【发布时间】:2014-06-10 12:03:29
【问题描述】:

我有两个实体,用户和消息。我只喜欢加载消息而不是消息所属的用户。

这通常有效,因为我没有在 linq 查询中包含相关实体。但是,如果我使用另一个查询单独加载用户以仅从该用户(名称)获取字符串,则它不起作用。

我正在使用 EF 6.1.0、没有代理生成的 POCO 和 WCF 服务来传递数据。不想要的 导航属性值随后被意外传输。

var message = context.messages.FirstOrDefault(m => m.id == 123);

var user = contect.users.FirstOrDefault(u => u.id = 456);

var message_username_composition = new M_U_C{ m = message, username = user.name };

return message_username_composition;

在这种情况下,我已经加载了消息的导航属性(用户),即使我不喜欢这样。

禁用 LazyLoading 没有帮助,只有使用单独的上下文才能解决问题。

除了使用两个上下文之外,还有其他方法吗?

这是设计的吗?

我也不喜欢手动将导航属性设置为 null 来解决这个问题,因为它也可能 被遗忘,因为人们没有意识到这种行为。

【问题讨论】:

  • 你为什么关心 message.User 是否设置?
  • 这是因为 EF 实现 identity map pattern 的方式。它知道您的消息与 id 为 456 的用户相关,因此它会自动填充该属性。
  • 在客户端我只通过外键更改用户,因为我没有加载所有用户。因此,我必须将导航属性设置为 null,这可能会导致错误。另外,如果不需要的话,我只是不喜欢将对象图包含到服务调用结果中。我很想知道为什么导航属性会被不同的查询加载。我感觉在这种情况下我无法控制自己的行为。因此,在服务器端,我可能会通过使用相同上下文的辅助查询意外引入包含。
  • Dean:我可以改变那个模式的行为吗?还是解决方案只是一个单独的上下文?
  • haim770:想想敏感数据,可能会意外通过服务边界!

标签: entity-framework


【解决方案1】:

您必须禁用延迟加载并使用AsNoTracking(),如下所示:

ctx.Configuration.LazyLoadingEnabled = false;
var message = context.messages.AsNoTracking().FirstOrDefault(m => m.id == 123);

【讨论】:

  • 我认为另一种解决方案是使用投影并仅选择那些需要的列。
猜你喜欢
  • 1970-01-01
  • 2022-01-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多