使用ID填充导航集合,而不引用关联的实体

时间:2014-12-03 19:24:32

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

我有两个实体

    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的集合(存在一定数量的类别,每个商家都会注册一些,例如&#34;私人教师 - 高中&#34;&# 34;私人教师 - 小学&#34;等。

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

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

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

但无法找到Collection Navigation属性的解决方案。

性能方面,这是一场灾难, 在一项测试中,我写了创建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秒钟。)

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

1 个答案:

答案 0 :(得分:1)

我相信你要找的是Stub Entities。本质上,您只需填写主键即可在本地创建一个对象,并使用该对象代替从数据库中获取整个内容。看到这个blog entry,虽然它有点旧。这也是类似的SO answer

基本上你会得到如下代码(但这是一个较旧的EF版本......见下文)

Category stub = new Category() {CategoryId = 3};
ctx.AttachTo("Categories", stub);

biz.Categories.Add(stub);

AttachTo将上下文中的实体设置为Unchanged,而不是添加。

但在这种情况下,ctx是一个ObjectContext。由于你正在使用EF6,你很可能想要使用DbSet.Attach方法,所以你可能会有类似的东西

context.Categories.Attach(stub);  

老实说虽然我不认为我已经在EF6中做到了这一点,所以我不肯定这是对的......但是这个概念仍然是一个Stub Entity,所以这就是什么您想要进行搜索。祝你好运!