使用 Dapper 进行多映射查询
Multi mapping query with Dapper
我的数据库中有这些 类 及其等效表:
public class Entity
{
public int Id { get; set; }
public List<EntityIdentifier> Identifiers { get; set; }
public BaseEntity()
{
Identifiers = new List<EntityIdentifier>();
}
}
public class EntityIdentifier
{
public int Id { get; set; }
public int EntityId { get; set; }
public string Code { get; set; }
public string Value { get; set; }
}
我想用 Dapper 查询数据库并自动映射数据。
我有这个多重映射的例子,来自 Dapper git page:
var sql =
@"select * from #Posts p
left join #Users u on u.Id = p.OwnerId
Order by p.Id";
var data = connection.Query<Post, User, Post>(sql, (post, user) => { post.Owner = user; return post;});
var post = data.First();
post.Content.IsEqualTo("Sams Post1");
post.Id.IsEqualTo(1);
post.Owner.Name.IsEqualTo("Sam");
post.Owner.Id.IsEqualTo(99);
但是,在这个例子中,每个 child (post) 都有一个 link 到它的 parent(用户)。
在我的例子中,parent(实体)指向 children(标识符)的 list。
我需要如何调整代码以适应我的情况?
这是我正在使用的 SQL 查询:
SELECT e.*, i.*
FROM Entity e INNER JOIN EntityIdentifier i ON i.EntityId = e.Id
这是我在 Dapper 相关网站某处找到的示例。这里的要点是有一个字典,您将 Entity.ID 作为键,将 Entity 作为字典值。然后在 lambda 表达式中检查字典是否已经包含实体,如果是,只需将 EntityIdentifier 添加到实体列表中,否则将 Dapper 返回的实体添加到字典中
string cmdText = @"SELECT e.*, i.*
FROM Entity e INNER JOIN Identifier i ON i.EntityId = e.Id";
var lookup = new Dictionary<int, Entity>();
using (IDbConnection connection = OpenConnection())
{
var multi = connection.Query<Entity, EntityIdentifier, Entity>(cmdText,
(entity, identifier) =>
{
Entity current;
if (!lookup.TryGetValue(entity.ID, out current))
{
lookup.Add(entity.ID, current = entity);
current.Identifiers = new List<EntityIdentifier>();
}
current.Identifiers.Add(identifier);
return current;
}, splitOn: "i.ID").Distinct();
return multi;
}
有时这会因参数 splitOn 而变得复杂。不确定是否需要重复添加到 Select 语句(我通常使用 IDTable 模式)
我的数据库中有这些 类 及其等效表:
public class Entity
{
public int Id { get; set; }
public List<EntityIdentifier> Identifiers { get; set; }
public BaseEntity()
{
Identifiers = new List<EntityIdentifier>();
}
}
public class EntityIdentifier
{
public int Id { get; set; }
public int EntityId { get; set; }
public string Code { get; set; }
public string Value { get; set; }
}
我想用 Dapper 查询数据库并自动映射数据。
我有这个多重映射的例子,来自 Dapper git page:
var sql =
@"select * from #Posts p
left join #Users u on u.Id = p.OwnerId
Order by p.Id";
var data = connection.Query<Post, User, Post>(sql, (post, user) => { post.Owner = user; return post;});
var post = data.First();
post.Content.IsEqualTo("Sams Post1");
post.Id.IsEqualTo(1);
post.Owner.Name.IsEqualTo("Sam");
post.Owner.Id.IsEqualTo(99);
但是,在这个例子中,每个 child (post) 都有一个 link 到它的 parent(用户)。 在我的例子中,parent(实体)指向 children(标识符)的 list。
我需要如何调整代码以适应我的情况?
这是我正在使用的 SQL 查询:
SELECT e.*, i.*
FROM Entity e INNER JOIN EntityIdentifier i ON i.EntityId = e.Id
这是我在 Dapper 相关网站某处找到的示例。这里的要点是有一个字典,您将 Entity.ID 作为键,将 Entity 作为字典值。然后在 lambda 表达式中检查字典是否已经包含实体,如果是,只需将 EntityIdentifier 添加到实体列表中,否则将 Dapper 返回的实体添加到字典中
string cmdText = @"SELECT e.*, i.*
FROM Entity e INNER JOIN Identifier i ON i.EntityId = e.Id";
var lookup = new Dictionary<int, Entity>();
using (IDbConnection connection = OpenConnection())
{
var multi = connection.Query<Entity, EntityIdentifier, Entity>(cmdText,
(entity, identifier) =>
{
Entity current;
if (!lookup.TryGetValue(entity.ID, out current))
{
lookup.Add(entity.ID, current = entity);
current.Identifiers = new List<EntityIdentifier>();
}
current.Identifiers.Add(identifier);
return current;
}, splitOn: "i.ID").Distinct();
return multi;
}
有时这会因参数 splitOn 而变得复杂。不确定是否需要重复添加到 Select 语句(我通常使用 IDTable 模式)