參考:https://www.cnblogs.com/FreeSql/p/11531404.html
https://blog.csdn.net/dotnetCore/article/details/101733455
https://www.cnblogs.com/youring2/p/automapper.html
1、定義的實體及Dto
public class UserEntity
{
public long Id { get; set; }
//導航屬性,ManyToMany
[Navigate(ManyToMany = typeof(UserOrganizeRelEntity))]
public List<OrganizeEntity> Organizes { get; set; }
}
public class OrganizeEntity
{
public long Id { get; set; }
/// <summary>
/// 關係表
/// </summary>
public List<UserOrganizeRelEntity> Rel { get; set; }
//導航屬性,ManyToMany
[Navigate(ManyToMany = typeof(UserOrganizeRelEntity))]
public List<UserEntity> Users { get; set; }
}
public class UserOrganizeRelEntity
{
public long UserId { get; set; }
public long OrganizeId { get; set; }
[Navigate("UserId")]
public UserEntity User { get; set; }
[Navigate("OrganizeId")]
public OrganizeEntity Organize { get; set; }
}
public class OrganizeDto
{
public long Id { get; set; }
public List<UserDto> Users { get; set; }
}
2、不使用導航屬性時,主要展示AutoMapper的映射,此時可以不使用Navigate,但從UserEntity映射到UserDto時,使用AutoMapper進行映射,稍微麻煩一點。
//FreeSql
var ar = await this.freeSql.Select<OrganizeEntity>()
.IncludeMany(a => a.Rel, then => then.Include(t => t.User))
.ToListAsync().ConfigureAwait(false);
//AutoMapper
x.CreateMap<UserEntity, UserDto>();
x.CreateMap<OrganizeEntity, OrganizeDto>()
//.ForMember(d => d.Users, opt => opt.ResolveUsing<CustomResolver>());
//.ForMember(d => d.Users, opt => opt.ResolveUsing(new CustomResolver()));
//.ForMember(d => d.Users, z => z.ResolveUsing(o => o.Rel.Select(t => t.User).ToList()));
.ForMember(y => y.Users, z => z.MapFrom(o => o.Rel.Select(t => t.User).ToList()));
public class CustomResolver : IValueResolver<OrganizeEntity, OrganizeDto, List<UserRelDto>>
{
public List<UserRelDto> Resolve(OrganizeEntity source, OrganizeDto destination, List<UserRelDto> destMember, ResolutionContext context)
{
//Mapper not initialized.
//Call Initialize with appropriate configuration.
//If you are trying to use mapper instances through a container or otherwise,
//make sure you do not have any calls to the static Mapper.Map methods,
//and if you're using ProjectTo or UseAsDataSource extension methods,
//make sure you pass in the appropriate IConfigurationProvider instance.
//try
//{
// var list = source.Rel.Select(x => x.User).ToList();
// return AutoMapper.Mapper.Map<List<UserRelDto>>(list);
//}
//catch(Exception ex)
//{
// string err = ex.ToString();
// return null;
//}
return source.Rel.Select(x => new UserRelDto
{
Id = x.User.Id,
}).ToList();
}
}
3、使用FreeSql導航屬性時,不再需要AutoMapper中的複雜映射,OrganizeEntity中的Users就有數據了。相對方便一些,但在OrganizeEntity和UserEntity中均需要設置[Navigate(ManyToMany = typeof(UserOrganizeRelEntity))],中間表也需要[Navigate("OrganizeId")], 以確定多對多導航關係。
//FreeSql
var ar = await this.freeSql.Select<OrganizeEntity>()
.IncludeMany(a => a.Users)
.ToListAsync().ConfigureAwait(false);
4、使用延時加載,定義時需要如:public virtual Order Order { get; set; },注意加上virtual,並將UseLazyLoading設爲true
5、使用自動同步實體結構到數據庫UseAutoSyncStructure(true),字符串長度,超過255時,需要手動指定[Column(DbType = "varchar(max)")],否則存儲超過255的一些數據時,數據庫的字段會變小,出現截斷錯誤。
6、FreeSql中不要使用嵌套事務,否則外部事務會報錯。