无法使用自动映射器映射内部导航 属性。英孚核心
Cannot map inner navigation property using automapper. EF Core
我有针对该特定问题的此类实体:Album
、Photo
。每个 Album
包含一个 集合 Photo
。
和 Dto 类: AlbumWithPhotosDto
,其中包含 集合 PhotoDto
。
在我的自动映射器配置文件中,我描述了所有实体的映射规则:
CreateMap<Photo, PhotoDto>()
.ForMember(dest => dest.AverageRate, opt => opt.MapFrom(src => src.Ratings.Average(r => r.Rate)))
.ForMember(dest => dest.RatesCount, opt => opt.MapFrom(src => src.Ratings.Count))
.ReverseMap();
CreateMap<Album, AlbumWithPhotosDto>()
.ForMember(dest => dest.PhotosNum, opt => opt.MapFrom(src => src.Photos.Count))
.ReverseMap();
首先,我使用了 LazyLoadingProxies
,当我尝试将 Album
映射到 AlbumWithPhotosDto
时。
我遇到异常:
Error mapping types.
Mapping types: Album -> AlbumWithPhotosDto DAL.Entities.Album ->
BLL.DataTransferObjects.AlbumWithPhotosDto
Type Map configuration: Album -> AlbumWithPhotosDto DAL.Entities.Album
-> BLL.DataTransferObjects.AlbumWithPhotosDto
Destination Member: Photos
然后我把懒加载改成显式加载如:
_context.Albums
.Include(a => a.Photos)
.Include(a => a.Author)
但是我又遇到了同样的异常。我该如何解决这个问题?
这里是类的补充定义:
public class Album : IEntity<int>
{
public int Id { get; set; }
/// <summary>
/// Album name.
/// </summary>
public string Name { get; set; }
/// <summary>
/// Album short description.
/// </summary>
public string Description { get; set; }
/// <summary>
/// Whether the other users can view and rate the album photos or not.
/// </summary>
public bool IsPrivate { get; set; }
/// <summary>
/// Foreign key, creator's id.
/// </summary>
public string AuthorId { get; set; }
/// <summary>
/// User who created the album but not obviously author of all photos.
/// </summary>
public virtual User Author { get; set; }
/// <summary>
/// Photos in album.
/// </summary>
public virtual ICollection<Photo> Photos { get; set; } = new HashSet<Photo>();
}
public class Photo : IEntity<int>
{
public int Id { get; set; }
/// <summary>
/// Optional photo short description.
/// </summary>
public string Description { get; set; }
/// <summary>
/// Path to the photo file on the hard drive.
/// </summary>
public string FileName { get; set; }
/// <summary>
/// Date and time of uploading.
/// </summary>
public DateTime UploadDate { get; set; }
/// <summary>
/// Photo ratings by users.
/// </summary>
public virtual ICollection<Rating> Ratings { get; set; } = new HashSet<Rating>();
/// <summary>
/// Foreigh key, author's id.
/// </summary>
public string AuthorId { get; set; }
public virtual User Author { get; set; }
public int AlbumId { get; set; }
public virtual Album Album { get; set; }
}
public class AlbumWithPhotosDto : IDtoMetadata
{
public int Id { get; set; }
public string Description { get; set; }
public string AuthorId { get; set; }
public int PhotosNum { get; set; }
public ICollection<PhotoDto> Photos { get; set; }
}
public class PhotoDto : IDtoMetadata
{
public int Id { get; set; }
public string Base64 { get; set; }
public string Description { get; set; }
public double AverageRate { get; set; }
public int RatesCount { get; set; }
public DateTime UploadDate { get; set; }
public string AuthorId { get; set; }
public ICollection<RatingDto> Ratings { get; set; }
}
您没有在查询中包含 Ratings
。因此,AutoMapper 基本上是在尝试在空集合上调用 .Average()
,因此失败。
将您的查询修改为 -
var albums = _context.Albums
.Include(a => a.Photos).ThenInclude(p => p.Ratings)
.Include(a => a.Author)
.ToList();
如异常消息中所述,问题出在 'AlbumWithPhotosDto' 中的 'Photos' 属性。将类型更改为 'List',然后尝试这种方式。
经过一步一步的投入,发现问题还是出在mapping config的那一行:
CreateMap<Photo, PhotoDto>()
.ForMember(dest => dest.AverageRate, opt => opt.MapFrom(src => src.Ratings.Average(r => r.Rate)))
解决方案是在评分为 0 时注意默认值。
CreateMap<Photo, PhotoDto>()
.ForMember(dest => dest.AverageRate, opt => opt.MapFrom(src => src.Ratings.Select(r => r.Rate).DefaultIfEmpty(0).Average()))
现在连 LazyLoadingProxies 都成功映射了,我之前认为它与自动映射器不兼容。
我有针对该特定问题的此类实体:Album
、Photo
。每个 Album
包含一个 集合 Photo
。
和 Dto 类: AlbumWithPhotosDto
,其中包含 集合 PhotoDto
。
在我的自动映射器配置文件中,我描述了所有实体的映射规则:
CreateMap<Photo, PhotoDto>()
.ForMember(dest => dest.AverageRate, opt => opt.MapFrom(src => src.Ratings.Average(r => r.Rate)))
.ForMember(dest => dest.RatesCount, opt => opt.MapFrom(src => src.Ratings.Count))
.ReverseMap();
CreateMap<Album, AlbumWithPhotosDto>()
.ForMember(dest => dest.PhotosNum, opt => opt.MapFrom(src => src.Photos.Count))
.ReverseMap();
首先,我使用了 LazyLoadingProxies
,当我尝试将 Album
映射到 AlbumWithPhotosDto
时。
我遇到异常:
Error mapping types.
Mapping types: Album -> AlbumWithPhotosDto DAL.Entities.Album -> BLL.DataTransferObjects.AlbumWithPhotosDto
Type Map configuration: Album -> AlbumWithPhotosDto DAL.Entities.Album -> BLL.DataTransferObjects.AlbumWithPhotosDto
Destination Member: Photos
然后我把懒加载改成显式加载如:
_context.Albums
.Include(a => a.Photos)
.Include(a => a.Author)
但是我又遇到了同样的异常。我该如何解决这个问题?
这里是类的补充定义:
public class Album : IEntity<int>
{
public int Id { get; set; }
/// <summary>
/// Album name.
/// </summary>
public string Name { get; set; }
/// <summary>
/// Album short description.
/// </summary>
public string Description { get; set; }
/// <summary>
/// Whether the other users can view and rate the album photos or not.
/// </summary>
public bool IsPrivate { get; set; }
/// <summary>
/// Foreign key, creator's id.
/// </summary>
public string AuthorId { get; set; }
/// <summary>
/// User who created the album but not obviously author of all photos.
/// </summary>
public virtual User Author { get; set; }
/// <summary>
/// Photos in album.
/// </summary>
public virtual ICollection<Photo> Photos { get; set; } = new HashSet<Photo>();
}
public class Photo : IEntity<int>
{
public int Id { get; set; }
/// <summary>
/// Optional photo short description.
/// </summary>
public string Description { get; set; }
/// <summary>
/// Path to the photo file on the hard drive.
/// </summary>
public string FileName { get; set; }
/// <summary>
/// Date and time of uploading.
/// </summary>
public DateTime UploadDate { get; set; }
/// <summary>
/// Photo ratings by users.
/// </summary>
public virtual ICollection<Rating> Ratings { get; set; } = new HashSet<Rating>();
/// <summary>
/// Foreigh key, author's id.
/// </summary>
public string AuthorId { get; set; }
public virtual User Author { get; set; }
public int AlbumId { get; set; }
public virtual Album Album { get; set; }
}
public class AlbumWithPhotosDto : IDtoMetadata
{
public int Id { get; set; }
public string Description { get; set; }
public string AuthorId { get; set; }
public int PhotosNum { get; set; }
public ICollection<PhotoDto> Photos { get; set; }
}
public class PhotoDto : IDtoMetadata
{
public int Id { get; set; }
public string Base64 { get; set; }
public string Description { get; set; }
public double AverageRate { get; set; }
public int RatesCount { get; set; }
public DateTime UploadDate { get; set; }
public string AuthorId { get; set; }
public ICollection<RatingDto> Ratings { get; set; }
}
您没有在查询中包含 Ratings
。因此,AutoMapper 基本上是在尝试在空集合上调用 .Average()
,因此失败。
将您的查询修改为 -
var albums = _context.Albums
.Include(a => a.Photos).ThenInclude(p => p.Ratings)
.Include(a => a.Author)
.ToList();
如异常消息中所述,问题出在 'AlbumWithPhotosDto' 中的 'Photos' 属性。将类型更改为 'List',然后尝试这种方式。
经过一步一步的投入,发现问题还是出在mapping config的那一行:
CreateMap<Photo, PhotoDto>()
.ForMember(dest => dest.AverageRate, opt => opt.MapFrom(src => src.Ratings.Average(r => r.Rate)))
解决方案是在评分为 0 时注意默认值。
CreateMap<Photo, PhotoDto>()
.ForMember(dest => dest.AverageRate, opt => opt.MapFrom(src => src.Ratings.Select(r => r.Rate).DefaultIfEmpty(0).Average()))
现在连 LazyLoadingProxies 都成功映射了,我之前认为它与自动映射器不兼容。