Dapper左联查询关联Brand实体映射异常,BrandId值错误问题排查
问题原因
你遇到的问题是Dapper多映射的splitOn参数配置错误,同时查询字段不全导致的,具体问题有两个:
- 错误配置了
splitOn参数:Dapper的多映射逻辑是按照查询结果的列顺序,从splitOn指定的列开始,将后续列映射给下一个实体。你当前指定splitOn: "BrandId",而查询结果中第二列就是c.BrandId,这会导致Dapper把第一列c.Id映射给Campaign后,从第二列开始的所有字段(包括Campaign的BrandId、StartDate、EndDate以及Brand的Id)全部映射给Brand实体,自然两个实体的属性值都会错乱。 - 未查询Brand实体的所需字段:你当前的SQL只查了
b.Id,就算映射逻辑正确,Brand的Name等属性也会是默认空值。
修正方案
按照以下两点修改代码即可:
- 调整SQL语句,先查询Campaign的所有字段,再查询Brand的所有需要映射的字段
- 将
splitOn参数改为"Id",因为查询完Campaign的所有字段后,第一个出现的Id列就是Brand的主键,Dapper会从这里开始拆分两个实体的映射字段
修正后的代码如下:
public async Task<Campaign> GetAsync(int id) { using var dbConnection = _context.CreateConnection(); string query = @"SELECT c.[Id], c.[BrandId], c.[StartDate], c.[EndDate],b.[Id], b.[Name] FROM [dbo].[Campaign] c LEFT JOIN [dbo].[Brand] b on c.[BrandId] = b.[Id] WHERE c.[Id] = @Id"; var campaign = await dbConnection.QueryAsync<Campaign, Brand, Campaign>(query, (campaign, brand) => { campaign.Brand = brand; return campaign; }, splitOn: "Id", param: new { Id = id }); return campaign.FirstOrDefault(); }
如果你的SqlEntityBase包含其他需要映射的公共字段,记得在SELECT语句中把Brand对应的字段也补充上即可。
内容的提问来源于stack exchange,提问作者TrypicalDev
相关产品推荐
相关产品推荐

