【问题标题】:AutoMapper - ProjectTo class with multiple properties of the same typeAutoMapper - 具有多个相同类型属性的 ProjectTo 类
【发布时间】:2019-05-27 08:30:46
【问题描述】:

最近发现了AutoMapper的ProjectTo<>方法,所以一直在玩弄。

到目前为止一切顺利,直到我遇到一个具有多个相同类型属性的类,例如:

public class RandomDto
{
    public int Id {get;set;}
    public ChildDto FirstChild {get;set;}
    public ChildDto SecondChild {get;set;}
}

它似乎为单个子关系生成 SQL,而不是为两者生成 SQL:

SELECT CASE
    WHEN [dtoRandom].[FirstChild_FK] IS NULL
    THEN CAST(1 AS BIT) ELSE CAST(0 AS BIT)
END, [t0].[Child_Description]
END, [dtoRandom].[Id]
FROM [Randoms] AS [dtoRandom]
INNER JOIN (
    SELECT [s].*
    FROM [Childs] AS [s]
) AS [t0] ON [dtoRandom].[FirstChild_FK] = [t0].[Id]

我试过了

.ProjectTo<RandomDto>(null, "FirstChild", "SecondChild")
.ProjectTo<RandomDto>(x=>x.FirstChild, x=>x.SecondChild)

两者都返回,第一个被填写,第二个为空

不确定我是否需要设置自定义别名或其他东西才能使其正常工作?

【问题讨论】:

  • 尝试将其编写为 LINQ 查询,不使用 AM。
  • 我遇到了同样的问题。如果我取出具有相同类型的属性之一,它会起作用。这听起来像是 Auto Mapper 中的一个错误(目前我使用的是 v9.0.0),虽然我试图在一个更简单的测试应用程序上模拟这个问题,但它没有发生。显然,不仅仅是拥有两个或多个相同类型的属性。

标签: c# automapper


【解决方案1】:

我遇到了同样的行为,并尝试通过对仅从原始导航属性派生的第二个导航属性使用另一个类来解决此问题。

public class ChildDtoTmp : ChildDto { }

public class RandomDto
{
    public int Id { get; set; }
    public ChildDto FirstChild { get; set; }
    public ChildDtoTmp SecondChild { get; set; }
}

这很好用,但是由于导航属性的类型有另一个导航属性,嵌套导航属性也会出现同样的奇怪行为。

public class ChildDto
{
    public int Id { get; set; }
    public InnerChildDto InnerChild { get; set; }
}

这导致属性FirstChild 和SecondChild 被映射,但只有FirstChild 的InnerChild 属性被映射。

也许这有助于某人弄清楚如何解决这个问题。

【讨论】:

    【解决方案2】:

    您的问题可能与名为MaxDepth 的稍微令人困惑的选项有关。我通过调用MaxDepth(1) 设法重现了这个确切的问题,据我了解,这应该只影响自引用实体,例如:

    class Foo
    {
        public Foo InnerFoo { get; set; }
    }
    

    在这种情况下,MaxDepth(1) 应该只映射在对象图中找到的第一个 Foo。这正是它发生的情况,但它也会影响以下结构(非常错误,恕我直言):

    class Bar
    {
        public Foo Foo1 { get; set; }
        public Foo Foo2 { get; set; }
    }
    

    上述场景中的MaxDepth(1) 将仅映射Foo1 属性,将Foo2 保持为null。

    哦,顺便说一句:设置MaxDepth,可以应用到他们所有的映射:

    var mapperCfg = new MapperConfiguration(cfg =>
    {
        cfg.AddProfile<SomeProfile>();
        cfg.ForAllMaps(SetMaxDepth);
    });
    
    private static void SetMaxDepth(TypeMap typeMap, IMappingExpression expression) => expression.MaxDepth(1);
    

    或单独到每个地图:

    var mapperCfg = new MapperConfiguration(cfg =>
    {
        cfg.CreateMap<SomeObject, SomeObjectDto>().MaxDepth(1);
    });
    

    【讨论】:

      猜你喜欢
      • 2019-03-06
      • 1970-01-01
      • 1970-01-01
      • 2022-08-19
      • 1970-01-01
      • 1970-01-01
      • 2021-07-24
      • 2017-04-04
      • 1970-01-01
      相关资源
      最近更新 更多