8

我使用实体框架 4.2(代码优先)将大量数据插入 SQL Server CE 4.0,与直接 SQL 插入相比,性能非常糟糕。

模型非常简单:

public class DocMember
{
    public DocMember() { this.Items = new List<DocItem>(); }

    public int Id { get; set; }

    public string Name { get; set; }
    public string MemberType { get; set; }
    public string AssemblyName { get; set; }

    public virtual IList<DocItem> Items { get; set; }
}

public class DocItem
{
    public int Id { get; set; }
    public DocMember Member { get; set; }
    public string PartType { get; set; }
    public string PartName { get; set; }
    public string Text { get; set; }
}

我有 2623DocMembers个和总共 7747 个DocItems要插入,我得到以下执行时间:

With SQL: 00:00:02.8
With EF:  00:03:02.2

我可以理解 EF 有一点开销,但它比 SQL 慢65 倍!

也许我的代码有问题,但它非常简单,我看不出有什么问题:

    private TimeSpan ImportMembersEF(IList<DocMember> members)
    {
        using (var db = new DocEntities())
        {
            db.Database.CreateIfNotExists();

            var sw = Stopwatch.StartNew();
            foreach (var m in members)
            {
                db.Members.Add(m);
            }

            db.SaveChanges();
            sw.Stop();
            return sw.Elapsed;
        }
    }

我还尝试调用SaveChanges每个插入的项目,或者每 100 或 200 个项目,但无济于事(这实际上使情况变得更糟)。

有没有办法提高性能,还是我必须使用 SQL 进行批量插入?


编辑:为了完整起见,这里是 SQL 插入的代码:http: //pastebin.com/aeaC1KcB

4

2 回答 2

6

您可以使用我的 SqlCeBulkCopy 库来加载批量数据,它模仿 SqlBulkCopy api:http ://sqlcebulkcopy.codeplex.com

于 2012-01-24T07:25:47.167 回答
1

它很慢,因为它没有批量插入。

当您在数据库上使用身份插入时,它必须在每个项目之后选择结果 ID 以分配给模型。这使得它真的很慢。

您的临时 SQL 没有选择 ID,因此在批处理时您可以一次提交所有语句。

用 NHibernate 编写的 Altho:

http://www.philliphaydon.com/2011/09/the-benefits-of-letting-the-orm-generate-the-identity-part-1/

我写过关于使用 ORM 生成的 ID 与 SQL 生成的 ID。

于 2012-01-24T00:09:14.123 回答