实体框架-从查询中动态设置模型属性值

本文关键字:设置 模型 属性 动态 框架 查询 实体 | 更新日期: 2023-09-27 18:25:53

我有以下型号:

public class A_DTO
{
    [Key]
    public string Id { get; set; }
    **public virtual B_DTO B { get; set; }**
    public virtual List<B_DTO> Bs { get; set; }
}
public class B_DTO
{
    [Key]
    public string Id { get; set; }
    public string AId { get; set; }
    public string UserId {get; set; }
    [ForeignKey("AId"]
    public virtual A_DTO A { get; set; }
    [ForeignKey("UserId"]
    public virtual User User { get; set; }
}

我正在尝试获得对象a_DTO的列表,但也包括属性B:

using AutoMapper.QueryableExtensions;
public IQueryable<A_DTO> GetAllA_DTO()
    {
        string userId = "8b6e9332-7c40-432e-ae95-0ac052904752";
        return context.A_DTO
                    .Include("Bs")
                    .Include("B")
                    .Project().To<A_DTO>()
                    .Where(a => a.Bs.Any(b => b.UserId == userId));
    }

如何根据设置UserId和A_DTO.Id动态设置此属性?

实体框架-从查询中动态设置模型属性值

以下是一组观察结果,您可能很幸运地在其中找到了解决方案:

代码优先模型中的B属性将导致a_DTO的数据库表中存在一个外键,该外键包含对B_DTO表的引用。实体框架将负责用B_DTOs表中引用行的数据填充对象来填充B导航属性,因此您将无法动态更改它。

如果源类型和目标类型相同,则无需使用Automapper Project方法。在您的示例中,它们看起来都是A_DTO。你确定你实际上不打算有一个包含在上下文中的实体"A"和通过Automapper从"A"映射的"A_DTO"吗?如果这是您真正想要的,那么您可以在.Select调用中拥有将A.Bs.FirstOrDefault(b => b.UserId == userId)映射到A_DTO.B的代码。但是,您将无法在自动映射器映射中基于userId应用筛选。

在没有看到任何Automapper Map设置代码的情况下,很难在这里了解意图。

顺便说一句,在我看来,当使用.Include时,最好使用接受表达式的重载。在您的情况下,includes将被重写:

.Include(a => a.B)
.Include(a => a.Bs)

使用此重载可以确保在重命名属性但未能更新.Include语句中的字符串时,会出现编译时错误。