没有自定义的 Dapper 中的多重映射 SQL

Multimapping in Dapper Without Custom SQL

有没有办法以通用方式在 Dapper 中使用多重映射,而不使用嵌入 C# 代码中的自定义 SQL?

例子见 Correct use of Multimapping in Dapper

是否有通用的方法来查询来自 2 个相关实体的数据,其中自动确定用于连接的公共字段?

使用 Dapper 进行多重映射是一种 运行 一次多个 SQL 查询然后 return 每个结果映射到特定对象的方法。

在这个问题的上下文中,Multimapping 甚至不相关,回复:您正在寻求一种从给定对象自动生成 SQL 查询并创建正确连接的方法,这将导致与多重映射无关的单个 SQL 查询。

我怀疑您要查找的内容与 Entity Framework 类似。您可能想要研究几个 Dapper 扩展项目,它们将生成您的一些 SQL。参见:Dapper.Rainbow VS Dapper.Contrib

不要这样做。更不要这样想!数据库持久且规范化。 Objects 易腐烂且经常非规范化,在编写 SQL 时,在两者之间转换是需要深思熟虑的事情。这真的不是自动化的步骤。长期、痛苦的经历让我们中的许多人确信,数据库抽象(表和连接)不应该只是被吸收到(或从代码中生成)。如果您还不确定,请使用已建立的 ORM。

另一方面,如果您绝对想控制您的 SQL,但 C# 中字符串文字中的 "embedding" 让您感到烦恼,那么我不能同意更多的。我可以推荐 QueryFirst,一个为您的查询生成 C# 包装器的 visual studio 扩展。您的 SQL 保留在一个真实的 SQL 文件中,经过语法验证,检查数据库引用,并且在每次保存时,QueryFirst 会生成一个带有 Execute() 方法的包装器 class,以及一个用于结果的 POCO .

根据multi-mapping,我假设您要填充嵌套的图表objects。一个很好的方法是在你的图表中为每个 class 使用一个 QueryFirst .sql,然后在 parent 的部分 class 中,添加一个 List 的 children。 (QueryFirst 生成的 POCO 分为 2 个部分 classes,您控制其中一个,该工具生成另一个。)

因此,对于客户及其订单的图表... 在parentsql

select * from customers where name like @custName

child sql

select * from orders where customerId = @customerId

在 parent 部分 class 中,用于预先加载...

    public List<Orders> orders;
    public void OnLoad()
    {
        orders = new getOrders().Execute(customerId); // property of the parent POCO
    }

或延迟加载...

    private List<Orders> _orders;
    public List<Orders> orders
    {
        get
        {                
            return _orders ?? _orders = new GetOrders().Execute(customerId);                
        }
    }

5 行代码,不包括括号,你有一个嵌套图,可以根据需要延迟加载或预先加载,界面可在代码中发现(输入参数和结果的智能感知)。它们可能是这些表中的数百列,您永远不需要 re-type 的名称,并且它们的数据类型将 transparently 流入您的 C#。

清晰的职责分离。全面控制。免责声明:我写了 QueryFirst :-)