使用 ID 填充导航集合,而不引用关联的实体
本文关键字:引用 关联 实体 ID 填充 导航 集合 使用 | 更新日期: 2023-09-27 18:32:56
我有两个实体
public class Business
{
public int BusinessId { get; set; }
public ICollection<Category> Categories = {get;set;}
}
和
public class Category
{
[Key]
public int CategoryId { get; set; }
public string Name { get; set; }
}
我从客户那里得到一个 Json,其中包含一个企业 ID 及其类别 ID 的集合(类别数量恒定,每个企业都注册了一些,例如"私立教师 - 高中"私立教师 - 小学"等(。
我希望能够创建业务并关联它们,而无需先加载相关类别。
我知道可以在一对一导航属性中使用外键属性:
//EXAMPLE OF 1-1
public class Business
{
[ForeignKey]
public int CatId{ get; set; }
public Category cat {get;set;}
}
但找不到集合导航属性的解决方案。
性能方面,这是一场灾难,在一次测试中,我写了创建 100 个企业,其中包含 3 个类别中的 1000 个类别,耗时超过 5 秒!
DateTime start = DateTime.Now;
for (int i = 0; i < 100; i++)
{
using (Model m = new Model())
{
Business biz = new Business();
biz.Categories.Add(m.Categories.Find(3));
biz.Categories.Add(m.Categories.Find(5));
biz.Categories.Add(m.Categories.Find(63));
}
}
DateTime end = DateTime.Now;
Console.WriteLine(end - start);
(使用相同的 DbContext 是错误的,只能让我达到 3 秒(。
我知道我可以使用解决方法并将所有类别存储在静态字典中并从那里获取,但是一个。我不确定 EF 不会每次都为它们创建新实例B.即使我克服了 A,我仍然想要一个 EF 解决方案来解决这个问题,这让我想也许我根本不应该使用 EF 并坚持旧的 T-SQL 和存储过程。也许 EF 无论如何都无法与专门设计的 T-SQL 竞争(不是少 60%,而是 600%(。与T-SQL相比,所有这些Lambadas,谓词和LINQ并不是对开发的简化。
您正在寻找的是存根实体。 本质上,您在本地创建一个对象,只填充主键,并使用它代替从数据库中获取整个内容。 请参阅此博客条目,尽管它有点旧。 还有这个类似的SO答案。
基本上,您将拥有如下所示的代码(但这是一个较旧的EF版本。见下文(
Category stub = new Category() {CategoryId = 3};
ctx.AttachTo("Categories", stub);
biz.Categories.Add(stub);
AttachTo 将实体放在上下文中作为"未更改",而不是"已添加"。
但在这种情况下,ctx 是一个 ObjectContext。 由于您使用的是 EF6,因此您很可能希望使用 DbSet.Attach 方法,因此您可能会有更像
context.Categories.Attach(stub);
老实说,虽然我认为我没有在 EF6 中这样做过,所以我不肯定这是对的......但这个概念仍然是一个存根实体,所以这就是你想要的搜索。 祝你好运!