And*_*son 4 c# entity-framework entity-framework-6
这是前一个问题的后续跟进,我试图找出代码运行缓慢的主要原因.我想我已经把它缩小到下面的一个最小例子.我有一个基本的数据库结构如下:
public class Foo
{
public int Id { get; set; }
public string Bar { get; set; }
}
public class FooContext : DbContext
{
public DbSet<Foo> Foos { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
现在,如果我有一个Foo对象列表,并希望将它们添加到数据库,建议的方法是使用AddRange().但是我注意到它花了很长时间,并且受到集合中项目数量的影响很小,即使是200这样的少量.所以我手动编写了它,并且中提琴,它运行得更快!
class Program
{
static void Main(string[] args)
{
var foos = Enumerable.Range(0, 200).Select(index => new Foo { Bar = index.ToString() });
// Make sure the timing doesn't include the first connection
using (var context = new FooContext())
{
context.Database.Connection.Open();
}
var s1 = Stopwatch.StartNew();
using (var context = new FooContext())
{
context.Foos.AddRange(foos);
context.SaveChanges();
}
s1.Stop();
var s2 = Stopwatch.StartNew();
using (var context = new FooContext())
{
// Ignore the lack of sanitization, this is for demonstration purposes
var query = string.Join(";\n", foos.Select(f => "INSERT INTO Foos ([Bar]) VALUES (" + f.Bar + ")"));
context.Database.ExecuteSqlCommand(query);
}
s2.Stop();
Console.WriteLine("Normal way: {0}", s1.Elapsed);
Console.WriteLine("Hard way : {0}", s2.Elapsed);
Console.ReadKey();
}
}
Run Code Online (Sandbox Code Playgroud)
我最初的想法是,实体框架可能正在为每个条目使用单独的事务,但是记录SQL显示情况并非如此.那为什么执行时间会有这么大差异呢?
在对您的问题进行一些研究时,我发现了这篇具有启发性的文章:http://www.codinghelmet.com/? path =howto/bulk-insert
这是一个引用:
插入的每个对象都需要两个SQL语句 - 一个用于插入记录,另外一个用于获取新记录的标识
插入多个记录时会出现问题.每个记录一次插入一个事实会加剧一个问题(但是这已经超出了你的问题的上下文,因为你已经在逐个插入测试).因此,如果您要插入200条记录,则会逐个执行400条sql语句.
所以根据我的理解,EF根本不是为批量插入而构建的.即使它像插入200条记录一样简单.这对我来说似乎是一个很大的失望.
我开始思考,"那么EF无论如何都是好事.它甚至不能插入几条记录".那么我会在两个方面给EF道具:
所以简单地说,似乎,如果你有一个需要插入一堆记录的操作,最好使用SqlBulkCopy.这可以在几秒钟内插入数千条记录.
我知道这可能不是你想听到的答案,因为相信我,因为我使用了很多EF,所以它也让我感到不安,但是我没有看到任何解决方法
| 归档时间: |
|
| 查看次数: |
1760 次 |
| 最近记录: |