1

当我没有在 POCO 模型中公开我的外键和子集合时,我遇到了 Dapper 的问题。让我们用两个实体举一个简单的例子:

Bike (Id, ModelName)
Tire (Id, Tread)

在数据库中,每个轮胎都有一个 Bike 的外键。但我的模型没有。从数据库中,我想将此结构具体化为Dictionary<Bike, IEnumerable<Tire>>. 每辆自行车(唯一)将有两个轮胎。

我可以使用以下查询选择这种一对多关系:

SELECT b.Id, b.ModelName, t.Id, t.Tread
FROM Bike b
JOIN Tire t ON b.Id = t.bike_id

为了使用 Dapper 进行映射,我执行了以下操作:

var dbResult = connection.Query<Bike, Tire, KeyValuePair<Bike, Tire>>("sql-query-above",
(a, s) => new KeyValuePair<Bike, Tire>(a, s);
splitOn: "Id");

并使用 LINQ 将该结果转换为我的字典:

Dictionary<Bike, IEnumerable<Tire>> dict = dbResult.GroupBy(g => g.Key, g => g.Value).ToDictionary(g => g.Key, g => g.AsEnumerable());

它正确地返回数据结构:

Bike #1
 - Tire #1
 - Tire #2
Bike #2
 - Tire #3
 - Tire #4

但这是实现这种数据结构的最有效方式吗?另一种方法是避免使用字典并创建其他暴露外键和关系的实体(例如 Bike 上的 Tyres 集合和 Tire 上的 FK),并使用此处描述的映射方法。但我想在我的模型中避免这种情况,因为它会导致很多额外的类。但是性能呢?这是更糟还是一样?

4

1 回答 1

0

我不是使用 Dapper 的专家,但我遇到了它的限制,就像你正在经历的那样。我遇到过类似的情况,我的对象中的一个属性是一个像你一样的集合。我发现创建第二个查询来使用扩展方法填充那些内部类型的集合更简单。

所以你可以先抓取所有的自行车,然后调用你的扩展方法来抓取轮胎数据,比如:

dict.WithTires();    

我知道这是对数据库的第二次调用,但权衡是您仍然可以骑自行车,而不必每次都获取轮胎信息。

此外,您可能会考虑将轮胎集合作为属性添加到您的自行车类中,恕我直言,这比使用字典更好。如果你有这样的事情:

public class Bike
{
    public int id { get; set; }
    public string modelName { get; set; }
    public IList<Tires> tires { get; set; }
}

public class Tires
{
    public int id { get; set; }
    public string tread { get; set; }
}

您可以轻松地创建一个扩展方法来获取单个自行车或一组自行车的轮胎数据:

Bike myBike = new Bike();
List<Bike> bikeCollection = new List<Bike>();

myBike.WithTires();
bikeCollection.WithTires();
于 2012-12-05T16:29:38.210 回答