我才刚刚开始研究Dapper.net,并且已经在尝试一些不同的查询,其中之一产生的异常结果令人意想不到。

我有2个表-PhotosPhotoCategories,其中两个表与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();

执行此操作后,并不是所有属性都被填充(尽管在DB表和我的对象中具有相同的名称)。

我注意到,如果我don't“选择p。*等”在我的SQL中,而是。

我明确声明了这些字段。

我想从查询中返回EXCLUDING p.CategoryId,然后填充所有内容(显然,针对我已从select语句中排除的Photo对象的CategoryId除外)。

但是我希望能够在查询中包括该字段,并使其以及SQL中查询的所有其他字段得到填充。

我可以从CategoryId类中排除Photo属性,并在需要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字段显示在第一种类型的任何位置。为了显示。

说我们有:

类别:A {Id,FooId} B {FooId,Name}
splitOn:“FooId”
数据:Id,FooId,FooId,名称


旧的拆分方法不考虑映射的实际基础类型。所以...它映射了Id => AFooId, FooId, Name => B
新方法知道A中的 Prop 和字段。当它第一次在流中遇到FooId时,不会启动拆分,因为它知道A具有一个需要映射的名为FooId的属性,下次看到FooId时,它将拆分,从而产生预期的结果。

关于c# - 使用Dapper.net的多映射查询的意外行为,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/6706038/

10-11 08:42