我的应用程序是如下的实体模型,并使用Dapper
public class Goal
{
public string Text { get; set; }
public List<SubGoal> SubGoals { get; set; }
}
public class SubGoal
{
public string Text { get; set; }
public List<Practise> Practices { get; set; }
public List<Measure> Measures { get; set; }
}
并有一个存储库,如下所示
public interface IGoalPlannerRepository
{
IEnumerable<Goal> FindAll();
Goal Get(int id);
void Save(Goal goal);
}
我遇到了两种情况,如下所示
请建议除了“循环”集合并编写大量SQL查询之外,还有更好的方法来处理这些场景。
答案 0 :(得分:4)
使用Dapper在SQL中进行大批量数据更新的最佳方法是使用复合查询。
您可以将一个查询中的所有对象检索为多个结果集,如下所示:
CREATE PROCEDURE get_GoalAndAllChildObjects
@goal_id int
AS
SELECT * FROM goal WHERE goal_id = @goal_id
SELECT * FROM subgoals WHERE goal_id = @goal_id
然后,你编写一个dapper函数来检索这样的对象:
using (var multi = connection.QueryMultiple("get_GoalAndAllChildObjects", new {goal_id=m_goal_id})) {
var goal = multi.Read<Goal>();
var subgoals = multi.Read<SubGoal>();
}
接下来批量更新大数据。你通过表参数插入来做到这一点(我在这里写了一篇文章:http://www.altdevblogaday.com/2012/05/16/sql-server-high-performance-inserts/)。基本上,您为要插入的每种类型的数据创建一个表,然后编写一个过程,将这些表作为参数并将它们写入数据库。
这是超高性能,并且尽可能优化,而且代码不是太复杂。
但是,我需要问:是否有任何意义保持“子目标”和所有其他对象的关系?一个简单的替代方法是创建一个XML或JSON文档,其中包含您的目标及其所有子对象序列化为文本,并将该对象保存到文件系统。它具有令人难以置信的高性能,非常简单,非常易于扩展,并且只需很少的代码。唯一的缺点是你不能用一些工作来编写一个SQL语句来浏览所有子目标。考虑一下 - 可能值得一想;)