简体   繁体   English

一对多而不暴露模型中的子集合和/或外键

[英]One-to-many without exposing child collections and/or foreign keys in the model

I'm having a problem with Dapper when I do not expose my foreign keys and child collections in the POCO model. 当我未在POCO模型中公开我的外键和子集合时,Dapper遇到了问题。 Let's take a simple example with the two entities: 让我们用两个实体的简单例子:

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

In the database each Tire has a foreign key to Bike. 在数据库中,每个Tire都有一个Bike的外键。 But my model does not. 但是我的模型没有。 From the database, I want to materialize this structure into a Dictionary<Bike, IEnumerable<Tire>> . 从数据库中,我想将此结构具体化为Dictionary<Bike, IEnumerable<Tire>> Where each Bike (unique) will have two tires. 每个自行车(唯一的)都有两个轮胎。

I could select this one-to-many relationship using the following query: 我可以使用以下查询选择一对多关系:

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

In order to map that using Dapper, I have done the following: 为了使用Dapper进行映射,我做了以下工作:

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

And to turn that result into my dictionary, using LINQ: 并使用LINQ将结果转换成我的字典:

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

And it correctly returns the data structure: 并正确返回数据结构:

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

But is this the most efficient way of materializing this data structure? 但这是实现此数据结构的最有效方法吗? An alternative would be to avoid the dictionary and create other entities that exposes the foreign keys and relationships (eg Tires collection on Bike and FK on Tire), and use a mapping approach like described here . 一种替代方法是避免使用字典,并创建其他暴露外键和关系的实体(例如,Bike上的Tires集合和Tyre上的FK),并使用此处所述的映射方法。 But I would like to avoid that in my model because it would result in lots of extra classes. 但是我想在模型中避免这种情况,因为这会导致很多额外的类。 But what about performance? 但是性能如何呢? Is this worse or the same? 这更糟还是一样?

I am no expert at using Dapper but I have run into limitations with it like the one you're experiencing. 我不是使用Dapper的专家,但是我遇到了一些局限性,就像您正在体验的那样。 I had a similar situation where one of the properties in my object was a collection like you tires. 我遇到过类似的情况,对象中的属性之一是像轮胎一样的集合。 I found it was simpler to create a second query to populate those inner types of collections with an extension method. 我发现创建第二个查询来使用扩展方法填充这些内部类型的集合更简单。

So you might just grab all the bikes first and then call your extension method to grab the tire data like: 因此,您可以先抓取所有自行车,然后调用扩展方法以抓取轮胎数据,例如:

dict.WithTires();    

I know its a second call to the database but the tradeoff is that you can still grab a bike without having to get the tires information everytime. 我知道它是数据库的第二个调用,但是折衷是您仍然可以骑自行车而不必每次都获取轮胎信息。

Also, you might think about adding the tires collection as a property to your bike class which IMHO is better than uing a dictionary. 另外,您可能会考虑将轮胎集合作为属性添加到自行车类中,恕我直言,这比使用字典要好。 If you had something like this: 如果您有这样的事情:

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; }
}

You could easily create an extension method for grabbing the tire data for an individual bike or a collection of bikes: 您可以轻松地创建扩展方法来获取单个自行车或一组自行车的轮胎数据:

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

myBike.WithTires();
bikeCollection.WithTires();

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM