c# - 集合中的 Dapper Multipmapping 集合

标签 c# sql dapper multi-mapping

在 Dapper 中,映射和对象包含列表并且每个列表项都有自己的列表的最佳方法是什么?

class Object1 {
    int Object1Id;
    List<Object2> object2s;
}

class Object2 {
    int Object2Id;
    List<Object3> object3s;
}

class Object3 {
    int Object3Id;
}

这是我想使用的 SQL

SELECT *
  FROM [Object1] o1
  left join [Object2] o2 on o1.Object1Id = o2.Object1Id
  left join [Object3] o3 on o2.Object2Id = o3.Object2Id

使用左连接是因为 Object1 可能没有 Object2 而 Object2 可能没有任何 Object3

我考虑过使用

connection.Query<Object1, Object2, Object3, Object1>

但是在字典中跟踪字典以将它们添加到列表中似乎需要很多行代码。

使用 QueryMultiple 会更好吗?

最佳答案

如果您使用的是 SQL Server 2016 或更高版本,我会使用 JSON。您可以将数据作为 JSON 文档返回,如下所示:

USE tempdb
GO

DROP TABLE IF EXISTS dbo.[Object1] 
DROP TABLE IF EXISTS dbo.[Object2] 
DROP TABLE IF EXISTS dbo.[Object3] 
GO

CREATE TABLE dbo.[Object1] ([Object1Id] INT PRIMARY KEY, [Value1] NVARCHAR(100));
CREATE TABLE dbo.[Object2] ([Object2Id] INT PRIMARY KEY, [Object1Id] INT, [Value2] NVARCHAR(100));
CREATE TABLE dbo.[Object3] ([Object3Id] INT PRIMARY KEY, [Object2Id] INT, [Value3] NVARCHAR(100));
GO

INSERT INTO dbo.[Object1] VALUES (1, 'Object 1 Value 1')
INSERT INTO dbo.[Object1] VALUES (2, 'Object 1 Value 2')
INSERT INTO dbo.[Object1] VALUES (3, 'Object 1 Value 3')
GO                        

INSERT INTO dbo.[Object2] VALUES (10, 1, 'Object 2 Value 1')
INSERT INTO dbo.[Object2] VALUES (20, 1, 'Object 2 Value 2')
INSERT INTO dbo.[Object2] VALUES (30, 2, 'Object 2 Value 3')
GO                       

INSERT INTO dbo.[Object3] VALUES (100, 10, 'Object 3 Value 1')
INSERT INTO dbo.[Object3] VALUES (200, 10, 'Object 3 Value 2')
INSERT INTO dbo.[Object3] VALUES  (300, 30, 'Object 3 Value 3')
GO

SELECT 
    *
FROM 
    [Object1] 
LEFT JOIN
    [Object2] AS Object2s ON [Object1].Object1Id = [Object2s].Object1Id
LEFT JOIN 
    [Object3] AS Object3s ON [Object2s].Object2Id = [Object3s].Object2Id
WHERE
    [Object1].Object1Id = 1
FOR
    JSON AUTO,WITHOUT_ARRAY_WRAPPER

有了 JSON 作为结果,很容易在你想要的类中反序列化它:

class Program
{
    class Object1 {
        public int Object1Id;
        public List<Object2> Object2s;
    }

    class Object2 {
        public int Object2Id;
        public List<Object3> Object3s;
    }

    class Object3 {
        public int Object3Id;
    }

    static void Main(string[] args)
    {
        using(var conn = new SqlConnection("Data Source=localhost; Initial Catalog=tempdb; Integrated Security=SSPI"))
        {
            var json = conn.ExecuteScalar<string>(@"               
                SELECT 
                    *
                FROM 
                    [Object1] 
                LEFT JOIN
                    [Object2] AS Object2s ON [Object1].Object1Id = [Object2s].Object1Id
                LEFT JOIN 
                    [Object3] AS Object3s ON [Object2s].Object2Id = [Object3s].Object2Id
                WHERE
                    [Object1].Object1Id = 1
                FOR
                    JSON AUTO,WITHOUT_ARRAY_WRAPPER
            ");                                

            var result = JsonConvert.DeserializeObject<Object1>(json.Replace("\"", "'"));

            Console.WriteLine(result.Object2s.Count);
        }
    }
}

性能也非常好。

关于c# - 集合中的 Dapper Multipmapping 集合,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47682255/

相关文章:

c# - 不可变字典、字典、C5

c# - 内部接口(interface)比内部 protected 构造函数*更难*访问?

c# - 尝试在 dapper 查询中映射多个对象时出现错误

c# - 如何将 C# 8.0 可空引用类型与 Entity Framework Core 模型一起使用?

c# - 如何更改 exe 文件的文件和产品版本

sql - 将多行合并为一个空格分隔的字符串

sql - 主键还是唯一索引?

c# - 表达式中未定义的函数 'Replace' ,是否替换?

c# - 为 Dapper 重置缓存

c# - 如何处理 postgreSQL 中复合类型的变化