如何让Automapper在非外键的Id字段上通过inner join抓取相关记录?
How to ask Automapper to grab related record by inner join on Id field which is not a foreign key?
我使用 Automapper 已经有一段时间了,到目前为止一切都很好。但最近我遇到了一些“限制”(或缺乏我的知识)。
让我给你一个简单的例子,有两个 类:
public class Consumable
{
public int ConsumableId { get; set; }
public string Description { get; set; }
public int SaleDepartmentId { get; set; }
}
public class SaleDepartment
{
public int SaleDepartmentId { get; set; }
public string Description { get; set; }
}
这两个实体存储了 SaleDepartment 的 Id,但是没有将 SaleDepartment 链接到 Consumable 的外键(我不希望它作为键),但是 SaleDepartment 在 SaleDepartmentId 上有 PrimaryKey
现在我的 DTO 看起来非常相似
public class ConsumableDTO
{
public int ConsumableId { get; set; }
public string Description { get; set; }
public int SaleDepartmentId { get; set; }
}
这是映射
Mapper.CreateMap<Consumable, ConsumableDTO>().ReverseMap();
所以每当我带来 ConsumableDTO 的集合时,我也想带来相关的 SaleDepartment 的描述,
如果有导航 属性 我会做这样的事情
Mapper.Map<ObservableCollection<Consumable>>
(context.Consumable.Project().To<ConsumableDTO>());
但是因为这样的键不存在,我如何告诉自动映射器根据我拥有的这些 ID 进行内部连接?
我花了两天时间找到了一种方法,但我不相信这是正确的方法,我想知道我是否在这里遗漏了一个技巧,并且有一种更简单或更好的方法可以使用自动映射器实现这一点.
这就是我获取相关记录的方法
var foo = new ObservableCollection<Consumable>(
(from c in context.Consumable.Project().To<ConsumableDTO>()
join sd in context.SaleDepartment on c.SaleDepartmentId equals sd.SaleDepartmentId
select new
{
consumable = c,
SaleDepartmentDescription = sd.Description
}).ToList()
.Select(p => Mapper.Map<ConsumableDTO, Consumable>(p.consumable, new Consumable()
{
SaleDepartmentDescription = p.SaleDepartmentDescription
})));
所以,这将抓取或消耗品然后内部连接 saledeparments 和 select 内部连接的描述形式,但似乎步骤很少,有没有更简单的方法告诉自动映射器,抓取相关的根据这个匹配的 Id 记录?
感谢您的关注和时间。
首先,我假设您的 DTO 应该包含 public string SaleDepartmentDescription { get; set; }
,因为您的问题提到了它,但它实际上并不存在。
如果您不使用 EF 迁移(这是一个合理的假设,否则您只需添加外键!),那么您可以通过在实体中添加键来实现这一点——这些键实际上不需要呈现在数据库中让 EF 加入它们,这只是告诉 EF 假装它们是。 (如果您使用的是 EF 迁移,那么这种方法将不起作用,因为它需要将键添加到数据库中。)
public class Consumable
{
public int ConsumableId { get; set; }
public string Description { get; set; }
public int SaleDepartmentId { get; set; }
[ForeignKey("SaleDepartmentId")]
public virtual SaleDepartment SaleDepartment { get; set; }
}
假设您的 DTO 确实 包含字符串 属性 SaleDepartmentDescription
然后 AutoMapper 将自动处理它,尽管您应该使用 ProjectTo 进行更有效的数据库查询:
var mappedDTOs = context.Consumable.ProjectTo<ConsumableDTO>().ToList();
我使用 Automapper 已经有一段时间了,到目前为止一切都很好。但最近我遇到了一些“限制”(或缺乏我的知识)。 让我给你一个简单的例子,有两个 类:
public class Consumable
{
public int ConsumableId { get; set; }
public string Description { get; set; }
public int SaleDepartmentId { get; set; }
}
public class SaleDepartment
{
public int SaleDepartmentId { get; set; }
public string Description { get; set; }
}
这两个实体存储了 SaleDepartment 的 Id,但是没有将 SaleDepartment 链接到 Consumable 的外键(我不希望它作为键),但是 SaleDepartment 在 SaleDepartmentId 上有 PrimaryKey
现在我的 DTO 看起来非常相似
public class ConsumableDTO
{
public int ConsumableId { get; set; }
public string Description { get; set; }
public int SaleDepartmentId { get; set; }
}
这是映射
Mapper.CreateMap<Consumable, ConsumableDTO>().ReverseMap();
所以每当我带来 ConsumableDTO 的集合时,我也想带来相关的 SaleDepartment 的描述, 如果有导航 属性 我会做这样的事情
Mapper.Map<ObservableCollection<Consumable>>
(context.Consumable.Project().To<ConsumableDTO>());
但是因为这样的键不存在,我如何告诉自动映射器根据我拥有的这些 ID 进行内部连接? 我花了两天时间找到了一种方法,但我不相信这是正确的方法,我想知道我是否在这里遗漏了一个技巧,并且有一种更简单或更好的方法可以使用自动映射器实现这一点.
这就是我获取相关记录的方法
var foo = new ObservableCollection<Consumable>(
(from c in context.Consumable.Project().To<ConsumableDTO>()
join sd in context.SaleDepartment on c.SaleDepartmentId equals sd.SaleDepartmentId
select new
{
consumable = c,
SaleDepartmentDescription = sd.Description
}).ToList()
.Select(p => Mapper.Map<ConsumableDTO, Consumable>(p.consumable, new Consumable()
{
SaleDepartmentDescription = p.SaleDepartmentDescription
})));
所以,这将抓取或消耗品然后内部连接 saledeparments 和 select 内部连接的描述形式,但似乎步骤很少,有没有更简单的方法告诉自动映射器,抓取相关的根据这个匹配的 Id 记录?
感谢您的关注和时间。
首先,我假设您的 DTO 应该包含 public string SaleDepartmentDescription { get; set; }
,因为您的问题提到了它,但它实际上并不存在。
如果您不使用 EF 迁移(这是一个合理的假设,否则您只需添加外键!),那么您可以通过在实体中添加键来实现这一点——这些键实际上不需要呈现在数据库中让 EF 加入它们,这只是告诉 EF 假装它们是。 (如果您使用的是 EF 迁移,那么这种方法将不起作用,因为它需要将键添加到数据库中。)
public class Consumable
{
public int ConsumableId { get; set; }
public string Description { get; set; }
public int SaleDepartmentId { get; set; }
[ForeignKey("SaleDepartmentId")]
public virtual SaleDepartment SaleDepartment { get; set; }
}
假设您的 DTO 确实 包含字符串 属性 SaleDepartmentDescription
然后 AutoMapper 将自动处理它,尽管您应该使用 ProjectTo 进行更有效的数据库查询:
var mappedDTOs = context.Consumable.ProjectTo<ConsumableDTO>().ToList();