首页 > 解决方案 > Mapster - 动态属性选择或忽略

问题描述

我有一个业务需要仅动态选择指定模型的属性,类似于 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 查询的最终选择中。

标签: c#entity-framework-coremappingmapster

解决方案


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

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

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


推荐阅读