如何防止EF7急切地修复导航属性? [英] How can I prevent EF7 from eagerly fixing up navigation properties?

查看:80
本文介绍了如何防止EF7急切地修复导航属性?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在Web应用程序中使用EF7时遇到问题,可以通过它使用一些帮助。我当前正在使用EF7 RC1。

I have an issue using EF7 in a web application with which I could use some help. I'm currently using EF7 RC1.

以下是一些说明我问题的模型。

Here are some models that illustrate my problem.

联系

public class Contact
{
    public Guid Id { get; set; }

    public string Desc { get; set; }
    public ContactType ContactType { get; set; }
}

ContactType

public class ContactType
{
    public Guid Id { get; set; }
    public string Desc { get; set; }

    public ICollection<Contact> Contacts { get; set; }
}

这些模型通过Fluent API相关,如下所示:

These models are related via Fluent API like this:

modelBuilder.Entity<Contact>(entity => {
     // abridged for clarity

     entity
        .HasOne(c => c.ContactType)
        .WithMany(ct => ct.Contacts)
        .IsRequired();                
});

我的需求是能够从加载了ContactType属性的数据库中检索联系人实体的集合。 EF使这变得非常容易:

My needs are to be able to retrieve a collection of Contact entities from the database with their ContactType property loaded. EF makes this quite easy:

using(var context = new MyDbContext()) {
    var contacts = await context
        .Contacts
        .Include(c => c.ContactTypes)
        .Where(/* some search criteria */)
        .ToListAsync();
}

问题在于,在加载Contact实体的ContactType属性时(发生这种情况(由于查询中对.Include()的调用),EF还会有帮助地加载每个ContactType实体的Contacts属性,从而导致无数个Contacts指向ContactTypes和ContactTypes指向Contacts。我了解为什么这是默认行为,并且在很多情况下都很有用,但是我需要将这些实体序列化为JSON并将其发送给客户端-这是只读情况。

The issue is that in loading the ContactType properties of the Contact entities (which happens due to the call to .Include() in the query), EF also helpfully loads the Contacts property of each ContactType entity, resulting in an infinite chain of Contacts pointing at ContactTypes and ContactTypes pointing at Contacts. I understand why this is the default behavior and that it's helpful in many cases, but my needs are to serialize these entities to JSON and send them down to the client - it's a read-only situation.

我的期望行为是EF返回带有已加载(非空)ContactType属性且其Contacts属性设置为null的Contacts集合。 EF可以做到这一点吗?有什么方法可以结束我想要的对象图,而不必手动使我不想填充的属性无效?

我尝试过的事情:


  • 将.AsNoTracking()附加到EF查询中(这似乎不会停止
    ContactType的Contacts属性

  • 告诉Json.NET不要序列化无限引用循环(
    是避免在序列化期间进行无限递归所必需的,但是
    仍然会导致

推荐答案

您无法避免EF加载ContactType。 Contacts集合,因为它实际上不是在加载它,而是使用已加载的Contact实例填充该集合。
这就是为什么使用AsNoTracking无效的原因,因为这既不是延迟加载也不是ChangeTracker的问题。

You can't avoid EF to load ContactType.Contacts collection, as it's not actually loading it but filling the collection with the loaded Contact instances. This is why using AsNoTracking has no efect, because is not a problem of lazy loading nor ChangeTracker.

您有三种可能的解决方案:

You have three possible solutions:


  1. 使用Json.NET ReferenceLoopHandling = ReferenceLoopHandling.Ignore ,但是正如您所说的那样,它将产生很多不必要的信息数据,因为您将获得每个ContactType的联系人集合

  2. 在ContactType.Contacts上使用 [JsonIgnore] 属性,这样被序列化程序忽略。但是它总是会忽略它,我不知道在其他情况下是否需要它

  3. 定义一个DTO,使用诸如Automapper之类的方法在其中映射数据(没有Contacts集合),序列化它

  1. Use Json.NET ReferenceLoopHandling = ReferenceLoopHandling.Ignore, but as you stated it will generate lot of unnecesary data, as you will get the collection of Contacts for every ContactType
  2. Use [JsonIgnore] attribute on ContactType.Contacts so it will be ignored by the serializer. But it will ignore it always, I don't know if you need it in other situations
  3. Define a DTO, use something like Automapper to map your data in it (without Contacts collection) and serialize it

我更喜欢第三个选项,因为我不喜欢将域模型对象发送给客户端,并且避免添加属性与域无关的域模型。

I would prefer the 3rd option as I don't like sending domain model objects to the client, and it avoid adding attributes to domain model not related with domain.

这篇关于如何防止EF7急切地修复导航属性?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆