c# - 使用 Dapper.net 进行多映射查询的意外行为

标签 c# asp.net mapping dapper

我才刚刚开始关注 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();

执行此操作时,并非所有属性都被填充(尽管数据库表和我的对象中的名称相同。

我注意到如果我“选择 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 => AFooId, FooId, Name => B

新方法 知道 A 中的属性和字段。当它第一次在流中遇到 FooId 时,它不会开始拆分,因为它知道 A 有一个名为 FooId 的属性,需要映射,下次它看到 FooId 时它会 split ,从而产生预期的结果。

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

相关文章:

asp.net - MSDeploy.exe 可以以管理员身份连接,但不能以任何其他 Windows 帐户身份连接

c# - 是否可以从 Controller 方法以编程方式调用 Razor 编译器?

c# - 为 ViewModel 选择什么方法?

elasticsearch - 为什么在Elasticsearch中创建索引时此新映射无法生效?

objective-c - RestKit 0.20 - 动态嵌套对象映射

c# - 比较游戏对象 增强现实游戏,Unity,Vuforia,C#

c# - 如何在现有 PDF 中嵌入字体?

c# - 如何从 C# 中的应用程序洞察中获取详细信息

mapping - 方案: pattern matching syntax

c# - 电子邮件的 HTML 模板未按预期呈现