具有QueryMultiple的Dapper多映射

我有一个返回多个结果集的存储过程。我用 dapper 执行这个

我有一个返回多个结果集的存储过程。我用 dapper 执行这个

其中一个结果集是人员加入检查,其中人员可以有许多检查。

最终目标是拥有具有检查对象集合的不同人员对象。

QueryMultiple给了我一个Sqlmapper.GridReader。我看到SqlMapper.GridReader.Read()的重载需要一个Func<TFirst, TSecond, TReturn>

有没有如何使用这个例子?

10

这是我如何得到它的工作:

var q = _sqlConnection.QueryMultiple("MySproc",
                                     myParams,
                                     commandType: CommandType.StoredProcedure);
var set1 = q.Read<Set1Type>();
var set2Func = new Func<Person, Check, Person>((p, c) => {
    p.CheckAlert = c;
    return p;
});
var set2 = q.Read(set2Func, "CheckId")
            .GroupBy(x => x.PersonId)
            .Select(x => {
                var person = x.First();
                person.Checks = x.Select(p => p.Check).ToArray();
                person.Check = null; // i really don't like this
                return person;
            })
            .ToArray();

正如评论所说,我不喜欢 Person 对象上不需要的 check 属性。

我仍然喜欢听到一个更好的方法。

9

这是我使用的解决方案的一个版本。我使用继承 hierachy 而不是将属性设置为 null 来回避 Ronnie 在his answer中提出的问题,但它相当于同样的事情。

这是 SQL:用户有项目和集合,项目可以在集合中。

CREATE TABLE Users
(id UNIQUEIDENTIFIER DEFAULT (NEWID()) NOT NULL,
name NVARCHAR (MAX) NULL,
email NVARCHAR (128) NULL,
PRIMARY KEY (id))
CREATE TABLE Items
(id UNIQUEIDENTIFIER DEFAULT (NEWID()) NOT NULL,
userId UNIQUEIDENTIFIER NOT NULL,
name NVARCHAR (MAX) NULL,
description NVARCHAR (MAX) NULL,
PRIMARY KEY (id),
FOREIGN KEY (userId) REFERENCES Users (id))
CREATE TABLE Collections
(id UNIQUEIDENTIFIER DEFAULT (NEWID()) NOT NULL,
userId UNIQUEIDENTIFIER NOT NULL,
name NVARCHAR (MAX) NULL,
layoutSettings NVARCHAR (MAX) NULL,
PRIMARY KEY (id),
FOREIGN KEY (userId) REFERENCES Users (id))
CREATE TABLE CollectedItems
(itemId UNIQUEIDENTIFIER NOT NULL,
collectionId  UNIQUEIDENTIFIER NOT NULL,
PRIMARY KEY CLUSTERED (itemId, collectionId),
FOREIGN KEY (itemId) REFERENCES Items (id),
FOREIGN KEY (collectionId) REFERENCES Collections (id))

现在数据模型类集合比我预期的要复杂一些,以便处理具有多个查询的 Dapper 多映射。

public class User
{
    public Guid Id { get; set; }
    public string Name { get; set; }
    public string Email { get; set; }
    public List<Item> Items { get; set; }
    public List<Collection> Collections { get; set; }
}
public class Item
{
    public Guid Id { get; set; }
    public Guid UserId { get; set; }
    public string Name { get; set; }
    public string Description { get; set; }
}
public class CoreCollection
{
    public Guid Id { get; set; }
    public Guid UserId { get; set; }
    public string Name { get; set; }
    public string LayoutSettings { get; set; }
}
public class PartialDataCollection : CoreCollection
{
    public Guid ItemId { get; set; }
}
public class Collection : CoreCollection
{
    public List<Guid> ItemIds { get; set; }
}
public class CollectedItem
{
    public Guid ItemId { get; set; }
    public Guid CollectionId { get; set; }
    public DateTime CreatedAt { get; set; }
}

最后,我们有控制器方法,它使用 Dapper 多映射与多个查询

[Route("GetUser/{id}")]
public User GetUser(Guid id)
{
    var sql = @"SELECT * FROM Users WHERE id = @id
                SELECT * FROM Items WHERE userId = @id
                SELECT * FROM Collections 
                    LEFT OUTER JOIN CollectedItems ON Collections.id = CollectedItems.collectionId  
                    WHERE userId = @id";
    using (var connection = new SqlConnection(ConnectionString))
    {
        var multi = connection.QueryMultiple(sql, new { id = id });
        var user = multi.Read<User>().Single();
        var items = multi.Read<Item>().ToList();
        var partialDataCollections = multi.Read<PartialDataCollection, CollectedItem, PartialDataCollection>(AddCollectedItem, splitOn: "itemId").ToList();
        user.Items = items;
        user.Collections = partialDataCollections.GroupBy(
            pdc => pdc.Id,
            (key, group) => new Collection
            {
                Id = key,
                UserId = group.First().UserId,
                Name = group.First().Name,
                LayoutSettings = group.First().LayoutSettings,
                ItemIds = group.Select(groupMember => groupMember.ItemId).ToList()
            }).ToList();
        return user;
    }
}
private PartialDataCollection AddCollectedItem(PartialDataCollection collection, CollectedItem collectedItem)
{
    if (collection != null && collectedItem != null)
    {
        collection.ItemId = collectedItem.ItemId;
    }
    return collection;
}

Ronnie 担心在his answer中设置person.Check = null我担心在我的模型中添加类PartialDataCollection会增加答案的复杂性。但是我看不到一个简单的方法。

(注:我在 Dapper GitHub 项目中提出了an issue。)

本站系公益性非盈利分享网址,本文来自用户投稿,不代表码文网立场,如若转载,请注明出处

(310)
BIM360是否具有用于FieldAPI的oAuth登录
上一篇
在Outlook桌面应用程序的后台使用动画gif
下一篇

相关推荐

发表评论

登录 后才能评论

评论列表(66条)