我正在尝试为电影商店网站设置一些东西(使用ASP.NET,EF4,SQL Server 2008),在我的场景中,我想允许“会员”商店导入他们存储的电影目录包含ActorName,MovieTitle和CatalogNumber的文本文件,如下所示:
演员,电影,CatalogNumber
John Wayne,True Grit,4577-12(每个记录重复)
这些数据将用于查找演员和电影,并创建一个“MemberMovie”记录,如果我使用这些表导入超过100个左右的记录,我的导入速度很糟糕:
我从文本文件将数据导入MemberMovie表的方法如下(文件成功上传后):
我的实施表现非常糟糕。我的期望是,这可以在几秒钟内完成(在文件上传之后)数千条记录,并且我有一些东西超出浏览器。
我的问题是:执行批量查找/插入的最佳方法是什么?我应该只调用一次SaveChanges而不是每个新创建的MemberMovie吗?使用像存储过程这样的东西来实现它会更好吗?
我的循环片段大致就是这样(为简洁起见而编辑):
while ((fline = file.ReadLine()) != null)
{
string [] token = fline.Split(separator);
string Actor = token[0];
string Movie = token[1];
string CatNumber = token[2];
Actor found_actor = ctx.Actors.Where(a => a.Name.Equals(actor)).FirstOrDefault();
if (found_actor == null)
continue;
Movie found_movie = found_actor.Movies.Where( s => s.Title.Equals(title, StringComparison.CurrentCultureIgnoreCase)).FirstOrDefault();
if (found_movie == null)
continue;
ctx.MemberMovies.AddObject(new MemberMovie()
{
MemberProfileID = profile_id,
CatalogNumber = CatNumber,
Movie = found_movie
});
try
{
ctx.SaveChanges();
}
catch
{
}
}
感谢任何帮助!
谢谢,丹尼斯
答案 0 :(得分:1)
<强>首先强>
前段时间我写了一篇关于在 1,n或所有行之后调用SaveChanges的答案:
实际上,在超过1行之后调用SaveChanges会更好,但毕竟不是。
<强>第二强>
确保你在Actors表中的名字和电影中的标题都有索引,这应该有所帮助。如果你只需要他的ID,你也不应该选择整个Actor:
而不是:
Actor found_actor = ctx.Actors.Where(a => a.Name.Equals(actor)).FirstOrDefault();
您可以选择:
int? found_actor_id = ctx.Actors.Where(a => a.Name.Equals(actor)).Select(a => a.ID).FirstOrDefault();
然后
Something.ActorID = found_actor_id;
这可以更快,因为不需要整个Actor实体,也不需要额外的查找,特别是与索引结合使用时。
<强>第三强>
如果发送一个非常大的文件,即使性能良好,仍有可能超时。您应该在单独的线程中运行此导入并立即返回响应。您可以为每个导入提供某种标识符,并允许用户通过此ID检查状态。