我才刚刚开始关注 Dapper.net,并且刚刚尝试了一些不同的查询,其中一个查询产生了我意想不到的奇怪结果。
我有 2 个表 - Photos
和 PhotoCategories
,它们与 CategoryID
相关
照片表
PhotoId (PK - int)
CategoryId (FK - smallint)
UserId (int)
照片类别表
CategoryId (PK - smallint)
CategoryName (nvarchar(50))
我的 2 个类(class):
public class Photo
{
public int PhotoId { get; set; }
public short CategoryId { get; set; }
public int UserId { get; set; }
public PhotoCategory PhotoCategory { get; set; }
}
public class PhotoCategory
{
public short CategoryId { get; set; }
public string CategoryName { get; set; }
{
我想使用多重映射返回一个 Photo
的实例,其中包含一个相关 PhotoCategory
的填充实例。
var sql = @"select p.*, c.* from Photos p inner
join PhotoCategories c
on p.CategoryID = c.CategoryID where p.PhotoID = @pid";
cn.Open();
var myPhoto = cn.Query<Photo, PhotoCategory, Photo>(sql,
(photo, photoCategory) => { photo.PhotoCategory = photoCategory;
return photo; },
new { pid = photoID }, null, true, splitOn: "CategoryID").Single();
执行此操作时,并非所有属性都被填充(尽管数据库表和我的对象中的名称相同。
我注意到如果我不
“选择 p.* 等”在我的 SQL
中,取而代之。
我明确说明了字段。
我想从查询中返回 EXCLUDING
p.CategoryId
,然后所有内容都会被填充(显然我从选择中排除的照片对象的 CategoryId 除外声明)。
但我希望能够在查询中包含该字段,并让它以及在 SQL
中查询的所有其他字段进行填充。
我可以从我的 Photo
类中排除 CategoryId
属性,并在我需要 ID 时始终使用 Photo.PhotoCategory.CategoryId
。
但在某些情况下,当我获得一个实例时,我可能不想填充 PhotoCategory
对象
照片对象。
有谁知道为什么会发生上述行为?这对 Dapper 来说正常吗?
最佳答案
我刚刚提交了一个修复:
class Foo1
{
public int Id;
public int BarId { get; set; }
}
class Bar1
{
public int BarId;
public string Name { get; set; }
}
public void TestMultiMapperIsNotConfusedWithUnorderedCols()
{
var result = connection.Query<Foo1,Bar1,
Tuple<Foo1,Bar1>>(
"select 1 as Id, 2 as BarId, 3 as BarId, 'a' as Name",
(f,b) => Tuple.Create(f,b), splitOn: "BarId")
.First();
result.Item1.Id.IsEqualTo(1);
result.Item1.BarId.IsEqualTo(2);
result.Item2.BarId.IsEqualTo(3);
result.Item2.Name.IsEqualTo("a");
}
如果在 first
类型中有一个字段,而该字段恰好在 second
类型中,则多映射器会感到困惑 ... AND ...被用作分割点。
为了克服现在 dapper 允许 Id
字段出现在第一种类型中的任何地方。为了显示。
假设我们有:
classes: A{Id,FooId} B{FooId,Name} splitOn: "FooId" data: Id, FooId, FooId, Name
旧的拆分方法没有考虑它映射的实际基础类型。所以...它映射了 Id => A
和 FooId, FooId, Name => B
新方法 知道 A
中的属性和字段。当它第一次在流中遇到 FooId
时,它不会开始拆分,因为它知道 A
有一个名为 FooId
的属性,需要映射,下次它看到 FooId
时它会 split ,从而产生预期的结果。
关于c# - 使用 Dapper.net 进行多映射查询的意外行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6706038/