使用Dapper对相关实体进行CRUD

时间:2012-08-20 03:48:04

标签: c# .net orm dapper

我的应用程序是如下的实体模型,并使用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);
}

我遇到了两种情况,如下所示

  1. 在检索数据(目标实体)时,需要检索层次结构中的所有相关对象(所有子目标以及实践和度量)
  2. 保存目标时,需要插入和/或更新所有相关数据
  3. 请建议除了“循环”集合并编写大量SQL查询之外,还有更好的方法来处理这些场景。

1 个答案:

答案 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语句来浏览所有子目标。考虑一下 - 可能值得一想;)