这个问题是哪种方法更好还是根本无关紧要。所以,假设我有一个类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": []
}
]
}
因此,类别模型具有导航属性的唯一问题是,当我请求项目列表时,它还会向我发送“Items”:[]。 它并没有影响我或任何东西,所以我想知道我是否应该使用导航方法或 .Where 方法。或者也许我应该考虑其他方法?
始终使用导航属性。 EF 将能够生成比您高效得多的查询(至少可能如此)。它也更更容易阅读。
就是这么说的。 不要使用 EF 对象作为数据契约。在“最好”的情况下,通过序列化器运行一个将执行上面的操作,而在常见情况下会导致循环引用异常。 您的合同应单独定义,这样就不存在循环引用。使用
Select
将集合从数据库类型转换为 API 类型。
在您的情况下,根据您的示例,正确的方法是在
ItemCategory
和
Item
之间创建一个连接表 Category
这样,您就可以更轻松地从任一大小进行查询。你的结构将是这样的:
public class Item
{
public int Id { get; set; }
public string Name { get; set; }
public virtual ICollection<ItemCategory> Categories { get; set; }
}
public class Category
{
public int Id { get; set; }
public string Name { get; set; }
public virtual ICollection<Item> Items { get; set; }
}
public class ItemCategory
{
public int CategoryId { get; set; }
public int ItemId { get; set; }
public virtual Item Item { get; set; }
public virtual Category Category { get; set; }
}
这样您就可以从类别和项目的角度进行搜索:
首先,按类别查找商品:
context.ItemCategories.Where(p=>p.CategoryId == id).ToList()
或
其次,找到该项目所属的类别列表:
context.ItemCategories.Where(p=>p.ItemId== id).ToList()
当然您可以选择不通过ItemCategory
查询。在这种情况下,你会做类似
context.Item.Where(p=>p.Id == id).Include(p=>p.Categories.Category).FirstOrDefault()
的事情。同样可以从 Category
完成,如
context.Category.Where(p=>p.Id == id).Include(p=>p.Items.Item).FirstOrDefault()
。那么,导航属性总是必要的吗?嗯,并非总是如此。仅当您从同一模型查询该属性时,才可以在模型中包含导航属性。
从上面的示例中,我们创建一个场景,您的应用程序不需要按项目查询类别。也就是说,您将始终按类别获取项目,而无需获取项目的类别。那么您就不需要
public Category Category {get; set;}
中的
ItemCategory
。因为你永远不会使用该属性。这同样适用于 public virtual ICollection<ItemCategory> Categories { get; set; }
模型中的 Item
。因此,根据经验,只有在您要使用导航时才正确包含它。 EF 将始终创建虚拟属性来应对这种情况。最后,您将得到更简洁的代码,并且没有您永远不会使用的不必要的属性。所有这一切始终取决于您的数据的查询方式。因此,请正确规划您的数据流。