我只是在使用ProjectTo时才收到错误,我无法理解底层问题。 (Automapper版本使用4.2.1.0) “LINQ to Entities中不支持指定的类型成员'标签'。 仅支持初始化程序,实体成员和实体导航属性。“ 我们也可以在DTO中进行这种操作,但我应该坚持只在实体方面进行操作。 请告诉我解决方法或解决方法,我可以在不升级版本的情况下处理此问题。 TIA 我希望实体的Tags属性的计算值需要映射到DTO的Tags属性,但是当我按照正常方式工作时这很好。
来源/目的地类型
public class Template : IEntity<int>
{
public string Name { get; set; }
public int Id { get; set; }
public string _Tags { get; set; }
[NotMapped]
public List<string> Tags
{
get { return _Tags == null ? null : JsonConvert.DeserializeObject<List<string>>(_Tags); }
set { _Tags = JsonConvert.SerializeObject(value); }
}
}
实体配置
internal sealed class TemplateConfig : EntityTypeConfiguration<Template>
{
public TemplateConfig()
{
Ignore(x => x.Tags);
HasKey(x => x.Id)
.Map(m =>
{
m.ToTable("Template");
m.Property(x => x.Id).HasColumnName("ID");
m.Property(x => x.Name).HasColumnName("Name");
m.Property(x => x._Tags).HasColumnName("Tags");
});
}
}
目的地DTO:
public class Template
{
public int Id { get; set; }
public string Name { get; set; }
public List<string> Tags { get; set; }
}
映射配置
Mapper.CreateMap<Template, DTO.Template>();
Mapper.CreateMap<DTO.Template, Template>();
//These are just for information, but getting error only when using ProjectTo. (Ignore about the OData thing)
public virtual async Task<IQueryable<TDto>> Get(ODataQueryOptions<TDto> query)
{
try
{
var expands = query.GetExpandedPropertyNames();
//Assume the collection has the data from db
var test = Collection.ToList();
//getting the exception here
return await Collection.ProjectTo<TDto>(null, expands).AsTask();
}
catch(Exception ex)
{
throw ex;
}
}
//Controller method
public override async Task<IQueryable<Template>> Get(ODataQueryOptions<Template> query)
{
try
{
List<Template> result = (await base.Get(query)).ToList();
return result.AsEnumerable().AsQueryable();
}
catch(Exception ex)
{
throw ex;
}
}
答案 0 :(得分:1)
这种情况正在发生,因为.ProjectTo<>(...)
正在SQL中为您构建select语句。由于.Tags
在您的对象之间映射,它被包含在select语句中,然后实体框架抱怨它不能这样做(因为NotMapped
属性)。
您可以使用普通ProjectTo<>(...)
,然后使用.ToList()
或.Select(Mapper.Map<TDto>)
,而不是使用Mapper.Map<List<TDto>>(list)
。
这应该有效,因为实体框架会从字符串字段填充你的Tags字段,而者automapper可以做好地图。
public virtual async Task<IQueryable<TDto>> Get(ODataQueryOptions<TDto> query)
{
try
{
var expands = query.GetExpandedPropertyNames();
//Assume the collection has the data from db
var test = Collection.ToList();
var entities = expands.ToList();
// you can either use .Select to project using LINQ
var dtos = await entities.Select(Mapper.Map<TDto>).AsTask();
// or you can use Mapper.Map to a list of entities.
dtos = await Mapper.Map<List<TDto>>(entities).AsTask();
return dtos;
}
catch(Exception ex)
{
// side note, don't throw ex, you'll lose the stack trace
throw;
}
}
答案 1 :(得分:0)
您是否尝试在MappingConfiguration中实现ignore?我无法确定你遇到问题的方向,但是有点像:
Mapper.CreateMap<Template, DTO.Template>()
.ForMember(dest => dest.Tags, opts => opts.Ignore());