【问题标题】:Should I always use navigation properties or use the .Where query?我应该始终使用导航属性还是使用 .Where 查询?
【发布时间】:2017-08-31 12:56:40
【问题描述】:

这个问题是哪种方法更好还是根本不重要。所以,假设我有一个类 Item 像这样

public class Item
{
    public int Id { get; set; }
    public string Name { get; set; }
    public virtual ICollection<Category> Categories { get; set; }
}

和引用的一个类别

public class Category
{
    public int Id { get; set; }
    public string Name { get; set; }
    public virtual ICollection<Item> Items { get; set; }
}

问题是当用户点击一个类别时,该类别中的所有项目都应该输出到一个列表中,该项目的类别也应该如此。

我可以使用类似的东西

_context.Items.Where(c => c.Category.Id == id);

并删除虚拟成员。 我问这个以及为什么我“想要”删除该成员的原因是因为当我使用 WebApi 为客户端获取 Items 表的 Json 数据时,它会输出如下内容:

{
    "Id": 1,
    "Name": "String",
    "Category": [
        {
        "Id": 1,
        "Name": "CName",
        "Items": []
        }, 
        {
        "Id": 1,
        "Name": "CName",
        "Items": []
        }
    ]
}

因此,对于 Category 模型具有导航属性的唯一问题是,当我请求项目列表时,它还会向我发送此“项目”:[]。 它不会影响我或任何东西,所以我想知道我应该使用 Navigation 方法还是 .Where 方法。或者也许我应该考虑其他一些方法?

【问题讨论】:

  • 我个人更喜欢在查询和项目/选择中使用导航属性来选择匿名类或将被序列化的自定义类。

标签: c# entity-framework database-design


【解决方案1】:

始终使用导航属性。 EF 将能够生成比您更有效的查询(可能,至少)。它也更容易阅读。

就是这么说的。 不要将您的 EF 对象用作数据契约。在最好的情况下,通过序列化程序运行一个序列化程序会执行上述操作,而在常见情况下会导致循环引用异常。

您的合同应单独定义,因此循环引用不存在。使用Select 将集合从 DB 类型转换为您的 API 类型。

【讨论】:

  • 所以我应该保留该属性,但创建另一个类用于序列化?该类是否应该包含对 Item 的引用(这也是一个传输对象)?
  • @E.Hoxha 是的。这正是典型的做法。 Item 将是另一个将 nav 属性返回其父级的传输对象(以防止循环引用)
  • 在这里读得不错:broloco.blogspot.com/2009/02/… 当我第一次做 POCO EF 时,我已经能够通过网络发送那些。但是,如果项目不是 POCO first EF ,那么我会按照您的建议创建 DTO ......对他们来说更具 viewmodel 风格。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-12-21
  • 2016-12-05
  • 1970-01-01
  • 1970-01-01
  • 2010-10-14
  • 1970-01-01
相关资源
最近更新 更多