【问题标题】:populating navigation collection using IDs without a reference to the associated entities使用不引用关联实体的 ID 填充导航集合
【发布时间】:2014-12-04 04:44:26
【问题描述】:

我有两个实体

    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 的集合(类别数量恒定,每个企业注册一些,例如“私人教师 - 高中”“私人教师 - 小学”等)。

我希望能够创建业务并关联它们,而无需先加载相关类别实体。

我知道可以在一对一的导航属性中使用 foreignKey 属性:

//EXAMPLE OF 1-1
 public class Business
{
    [ForeignKey]
    public int CatId{ get; set; }
    public Category cat {get;set;}
}

但找不到集合导航属性的解决方案。

就性能而言,这是一场灾难, 在一个测试中,我编写了创建 100 个企业,其中 1000 个类别中有 3 个类别花费了 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 秒)。

我知道我可以使用一种解决方法并将我的所有类别存储在静态字典中并从那里获取但是 A. 我不确定 EF 不会每次都为它们创建新实例 B. 即使我克服了 A,我仍然想要一个 EF 解决方案来解决这个问题,这让我想也许我根本不应该使用 EF 并坚持旧的 T-SQL 和存储过程。 也许 EF 无法以任何方式与专门设计的 T-SQL 竞争(不是减少 60%,而是减少了 600%)。 与 T-SQL 相比,Lambadas、谓词和 LINQ 并没有对开发进行太多简化。

【问题讨论】:

  • 我对@9​​87654325@ 和Category 之间的关系有点困惑。那应该是多对多还是一对多?因为从您给出的示例来看,您将其视为一对多。
  • 实际上两者都可以,两种情况的性能都很糟糕(今天检查过)我的连接或设置可能有问题吗?因为我不敢相信这就是 EF 的反应。其他机器上也一样吗?

标签: c# entity-framework entity-framework-6


【解决方案1】:

我相信您正在寻找的是存根实体。本质上,您在本地创建一个仅填充主键的对象,并使用它来代替从数据库中获取整个内容。看到这个blog entry 虽然它有点旧了。还有这个类似的SO answer

基本上你会得到类似下面的代码(但这是一个较旧的 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 中没有这样做,所以我不肯定这是正确的......但这个概念仍然是一个存根实体,所以这就是您想要进行搜索的内容。祝你好运!

【讨论】:

  • 听起来不错!明天我会在我签名作为答案之前对其进行测试。我在网上搜索了几个小时,还没有听说过这种聪明的技术。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-05-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-09-27
相关资源
最近更新 更多