FreeSql、AutoMapper處理多對多查詢映射。

參考: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中不要使用嵌套事務,否則外部事務會報錯。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章