实体框架有选择地从上下文中保存跟踪的实体并批量插入其他实体

bulkinsert c# entity-framework sqlbulkcopy

我是Entity Framework的新手。我遇到过一个我拥有实体的场景:

public class Company{
    public int Id { get; set; }
    public string Name { get; set; }
    public IList<Project> Projects{ get; set; }
}

public class Project
{
    public int Id { get; set; }
    public List<ProjectRecord> ProjectRecords { get; set; }
    public DateTime ProjectDate { get; set; }
}

public class ProjectRecord
{
    public int Id { get; set; }
    public virtual Project Project{ get; set; }
    public string Status { get; set; }
}

我创建我的上下文,加载雇主然后将雇主对象传递给另一个类,该类将一个项目添加到我的雇主实体,然后我从一个文件加载大约300,000个项目记录,并将该项目记录列表添加到项目中。

实体框架正在跟踪所有这些,虽然它不是特别快,但也不算太糟糕。

慢的部分是我在上下文中调用SaveChanges()。我希望能够从我的上下文中分离项目记录列表并在没有它们的情况下保存项目,然后使用https://efbulkinsert.codeplex.com/提供的批量插入扩展来单独批量插入ProjectRecords。但是我找不到分离ProjectRecords的方法。

因此,我尝试批量插入整个Project实体:

        context.BulkInsert(context,
            context.ChangeTracker.Entries()
                .Where(x => x.State == EntityState.Added)
                .Select(x => x.Entity)
                .OfType<Project>()
                .ToList());

        context.SaveChanges();

但是,这似乎需要很长时间才能对数据库执行任何操作。因此,我认为我完全错了。

当我将项目添加到Employer实体时,我没有可用的上下文,如果我可以避免它,我不想让它可用,因为我试图将它们分开。

有没有办法提高性能,使用批量插入扩展或sql批量复制从我在上下文中调用SaveChanges?

任何帮助是极大的赞赏。

一般承认的答案

如果可能的话,建议不要在加载时将ProjectRecords附加到上下文中。你可以使用类似的东西

Dictionary<Project, List<ProjectRecord>>

保存它们并帮助检索Project并在保存时设置ProjectRecord.Project



许可下: CC-BY-SA with attribution
不隶属于 Stack Overflow
这个KB合法吗? 是的,了解原因
许可下: CC-BY-SA with attribution
不隶属于 Stack Overflow
这个KB合法吗? 是的,了解原因