Dapper 中的多映射.在斯皮尔顿中收到错误



*你能解释一下多重地图中的拆分功能吗 *

我正在尝试使用 Dapper ORM 从数据库中获取数据。我收到以下错误System.ArgumentException:使用多映射 API 时,如果您有 Id 以外的键,请确保设置 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; }
 }

/* 搜索功能从表中获取 dat */

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

多地图功能实际上更适用于以下场景:

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;

最新更新