Dapper 中的多重映射。在 SpiltOn 中接收错误
Posted
技术标签:
【中文标题】Dapper 中的多重映射。在 SpiltOn 中接收错误【英文标题】:Multi Mapping in Dapper. Receiving the error in SpiltOn 【发布时间】:2016-02-25 07:28:11 【问题描述】:*你能解释一下multimap中的Split on功能吗*
我正在尝试使用 Dapper ORM 从数据库中获取数据。我收到以下错误 System.ArgumentException : 使用多映射 API 时,如果您的键不是 Id,请确保设置 splitOn 参数 参数名称:splitOn
public abstract class Domain
public Guid Id get; set;
public abstract class ItemBase : Domain
private IList<Image> images = new List<Image>();
public Guid? ParentId get; set;
public string Name get; set;
public IList<Image> Images get return images;
public class Meal : ItemBase
public class Item : ItemBase
private IList<Meal> meals = new List<Meal>();
public IList<Meal> Meals get return meals; ;
public class Image : Domain
public byte Img get; set;
public string Description get; set;
public class MealImageLink : Domain
public Guid ItemId get; set;
public Guid ImageId get; set;
/* 从表中获取数据的搜索函数 */
private List<Meal> SearchMeals(Guid id)
var query = @"SELECT meal.[Name],meal.[Description],meal.
[Price],mealImage.[Image] as Img
FROM [MealItems] as meal
LEFT JOIN [MealImageLink] mealImageLink
on meal.Id= mealImageLink.MealItemId
LEFT JOIN [Images] mealImage on
mealImageLink.ImageId=mealImage.Id
WHERE meal.[ParentId]=@Id";
List<Meal> meals = ( _connection.Query<Meal, MealImageLink, Image, Meal>
(query, (meal, mealLink, mealImage) =>
meal.Images.Add(mealImage);
return meal;
, new @Id = id )).ToList();
return meals;
【问题讨论】:
【参考方案1】:多地图功能更适用于以下场景:
select foo.Id, foo.whatever, ...,
bar.Id, bar.something, ...,
blap.Id, blap.yada, ...
from foo ...
inner join bar ...
left outer join blap ...
或者更懒惰但并不少见:
select foo.*, bar.*, blap.*
from ...
inner join bar ...
left outer join blap ...
但是在这两种情况下,有一种清晰明了的方法可以将水平范围划分为多个分区;基本上,每当您看到名为Id
的列时,它就是下一个块。名称Id
可配置为方便起见,并且可以是列的分隔列表,用于每个表具有不同主键名称的情况(因此User
可能有UserId
等)。
您的情况似乎与此完全不同。看起来您目前只选择了 4 列,没有特别的方式将它们分开。我建议在这种情况下,通过不同的 API 更容易填充您的模型 - 特别是 dynamic
API:
var meals = new List<Meal>();
foreach(var row in _connection.Query(sql, new @Id = id ))
string name = row.Name, description = row.Description;
decimal price = row.Price;
// etc
Meal meal = // TODO: build a new Meal object from those pieces
meals.Add(meal);
只需不指定任何<...>
即可访问dynamic
API。完成后,按名称访问列,它们的类型隐含它们被分配的内容 - 因此类似于:
decimal price = row.Price;
注意:如果你想使用“内联”的row
数据,那么只需尽快,即
// bad: forces everything to use dynamic for too long
new Meal(row.Name, row.Description, row.Price);
// good: types are nailed down immediately
new Meal((string)row.Name, (string)row.Description, (decimal)row.Price);
这有帮助吗?
Tl;dr:我只是认为多重映射与您的查询无关。
编辑:这是我对您打算做什么的最佳猜测 - 它根本不适合多地图:
var meals = new List<Meal>();
foreach (var row in _connection.Query(query, new @Id = id ))
meals.Add(new Meal
Name = (string)row.Name,
Images =
new Image
Description = (string)row.Description,
Img = (byte)row.Img
);
return meals;
【讨论】:
你能详细解释一下代码下面的动态API ` var foods = new ListList<Meal> meals = ( _connection.Query<Meal, MealImageLink, Image, Meal> (query, (meal, mealLink, mealImage) => meal.Images.Add(mealImage); return meal; , new @Id = id ,splitOn: "Name")).ToList();
,我也收到同样的错误跨度>
“我已将代码重新排列为...” - 确实;您告诉它按名为Name
的列拆分水平分区。唯一称为Name
的列发生在第一列。绝对无法获取任何其他分区的任何数据,......所以......消息正确地识别出一些非常错误的东西。
@chaaru "你能详细解释一下吗...";你有 4 列,可以根据我显示的代码提取。一旦你有了这 4 个值,就可以构造一个 Meal
(你确实选择了这 4 个值,等等)。我不确定你想让我在那里添加什么......
:"你能详细解释一下吗。"我仍然怀疑我必须在 foreach(var row in _connection.Query(sql, new @Id = id ))
这个或其他任何地方编写执行命令。请给出完整的代码。我是这个 Dapper 和 C# 的新手以上是关于Dapper 中的多重映射。在 SpiltOn 中接收错误的主要内容,如果未能解决你的问题,请参考以下文章