【问题标题】:Mapster - Dynamic property selection or ignoreMapster - 动态属性选择或忽略
【发布时间】:2021-08-14 03:20:28
【问题描述】:

我的业务需要仅动态选择指定模型的属性,类似于 OData 选择子句。我目前正在使用 Mapster 的 ProjectToType 功能从 EF Core 实体填充视图模型。

有没有办法告诉 Mapster 在它生成的查询中只选择给定的属性列表?还是一种获取完整模型映射并在运行时更改 TypeAdapterConfig 实例中的映射以忽略不在给定属性列表中的属性的方法?

最终的解决方案需要是通用的并且可以使用导航属性,因为它将应用于数据库中的所有实体。在某些情况下,我们还使用了 DynamicLinq,不确定它是否可以在 Mapsters ProjectToType 功能之上使用。

例子:

实体(部分属性因长度而省略):

namespace DataAccess.Entities
{
    public class Series
    {
        public Guid Id { get; set; }
        public string Description { get; set; }
        public long? StackRank { get; set; }
        public string EntityId { get; set; }
        // Other properties
    }

    public class Model
    {
        public Guid Id { get; set; }
        public string Description { get; set; }
        public string EntityId { get; set; }
        public long? StackRank { get; set; }
        public Guid SeriesId { get; set; }
        
        public virtual Series Series { get; set; }
        
        // Other properties

    }
}

查看模型(长度省略了一些属性):

namespace Models
{
    public class Model
    {
        public Guid Id { get; set; }
        public string Description { get; set; }
        public string EntityId { get; set; }
        public long? StackRank { get; set; }
        public Guid SeriesId { get; set; }
        
        public virtual Series Series { get; set; }
        
        // Other properties
    }
    
    public class Series
    {
        public Guid Id { get; set; }
        public string Description { get; set; }
        public long? StackRank { get; set; }
        public string EntityId { get; set; }
        // Other properties
    }
}

给定一个 rest 调用以获取所有模型视图模型的列表,并包含此属性列表:

var properties = new List<string> {
"Id",
"EntityId"
"Description",
"Series.Id",
"Series.Description",
"Series.EntityId"
}

结果将返回仅包含这些属性的某种类型的字典、动态或匿名对象,而其他属性甚至不会包含在所创建的 SQL 查询的最终选择中。

【问题讨论】:

  • 我可以在没有 Mapster 的情况下做到这一点。我认为在这种情况下不需要。
  • 您可能可以即时生成映射器并使用条件忽略配置:github.com/MapsterMapper/Mapster/wiki/…
  • 我认为返回部分填充的实体与 OData(即 REST)原则不一致。只是一个主要的反对意见,当这些实体被放回时你会怎么做?要么遵循协议,要么不使用 OData。返回字典甚至是对 REST 的进一步背离。我不明白你为什么不想返回完整的实体。
  • @GertArnold - 我们的业务用例是我们的用户可以自定义我们的网格以查看他们想要的任何列,如果我们不这样做,我们不必提取所有列的数据'不必。例如,我们的一些数据库表有 50 列,但用户只关心 5 列。另外,我们使用 PATCH 而不是 PUT

标签: c# entity-framework-core mapping mapster


【解决方案1】:

最后,我决定采用 Arca Artem 的建议,稍作改动。我使用反射来获取模型所有属性的列表并缓存它们。之后,我将缓存的属性与要包含的属性列表进行了比较,并忽略了不在两个列表中的属性。有点像这样:

var clonedConfig = mapsterInstance.Clone();
clonedConfig.ForType<TSource, TDestination>().Ignore(propertiesToIgnore);
var models = await query.ProjectToType<TDestination>(clonedConfig).ToListAsync();

也许不是最优雅的解决方案,但它足以满足我的需要。我还设置了我们的 json 序列化程序以忽略空值。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-03-04
    • 2013-03-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多