【问题标题】:Filter a property List inside in include在包含中过滤属性列表
【发布时间】:2021-08-22 00:26:52
【问题描述】:

我需要你的帮助

我尝试用 .Include 创建一个 linq 句子,但我的问题是我在 mi 类中有一个属性,它是一个列表,它是我的类:

public partial class document
{
    public int       ID     { get; set; }
    public string    Amount { get; set; }
    public List<Log> Log    { get; set; }
}

这是课程日志

public partial class Log
{
    [Key]
    public int ID { get; set; }

    [Required]
    public Status Status { get; set; }

    [Column(TypeName = "text")]
    public string Description { get; set; }

    public DateTime? DateLog { get; set; }

    public int? DocumentID{ get; set; }

    [ForeignKey("DocumentID")]
    public Document Document{ get; set; }
}

我的问题是我不知道如何过滤文档内的列表记录以包含在类中,我需要获取整个文档类并过滤仅显示状态=已接收的日志,文档可以有许多日志

你尝试这样做,但没有成功

 var Result = db.document
    .Include(m => m.Log.Where(c => c.Status == Status.Recieved));

我收到了下一个错误

“包含路径表达式必须引用在类型上定义的导航属性。引用导航属性使用虚线路径,集合导航属性使用选择运算符。\r\n参数名称:路径”

感谢您的帮助

【问题讨论】:

  • 此语法仅在 EF Core 5.x 中支持

标签: c# asp.net-mvc entity-framework linq model-view-controller


【解决方案1】:

Include 用于包含与实体的关系并获取相关的实体属性,查看文档 - Fetching related data
如果你像这样选择没有Include的文档

var documents = await db.document.ToListAsync();

您将获得 Log 将为空的文档数据。

你需要这样的东西:

var result = await db.document
                     .Select(w=> new 
                     {
                         document = w,
                         log = w.Log.Where(c => c.Status == Status.Recieved).ToList()
                     }).ToListAsync();

【讨论】:

  • 感谢您的回答,但我有下一个错误:LINQ to Entities 无法识别方法 'Boolean[] ToArray[Boolean](System.Collections.Generic.IEnumerable`1[System.Boolean ])' 方法,并且该方法不能翻译成 store 表达式。
  • Include 仅用于获取相关数据,而不用于加入。您可以从此查询中删除 Include。
  • @SvyatoslavDanyliv 你在查询中包含绝对正确,已修复。删除了一个不完全正确的陈述。谢谢。
【解决方案2】:

EF 确实支持一些自动过滤规则,以帮助处理软删除 (IsActive) 和多租户 (ClientId) 等概念,但并不真正适用于您想要应用“已接收”文档等情境过滤器的场景.

EF 实体应被视为反映数据状态的模型。过滤这样的结果更像是一种视图模型状态,您可以通过投影来实现:

var result = db.document.Select(d => new DocumentViewModel
{
    DocumentId = d.DocumentId,
    // .. fill in other required details...
    ReceivedLogs = d.Logs
        .Where(l => l.Status == Status.Received)
        .Select(l => new LogViewModel
        {
             // Fill needed log details...
        }).ToList()
}).ToList();

否则,如果您正在对实体执行本地操作并且只想要文档和收到的日志条目:

var documentDetails = db.document
    .Where(d => d.DocumentId == documentId)
    .Select(d => new 
    {
        Document = d,
        ReceivedLogs = d.Logs
            .Where(l => l.Status == Status.Received)
            .ToList()
    }).Single();

documentDetails.Document.Logs 不会被预先加载,如果你访问它会触发延迟加载,但 documentDetails 确实包含相关的 Received 日志以进行访问。作为匿名类型,不适合返回,只能在本地消费。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2022-01-25
    • 1970-01-01
    • 1970-01-01
    • 2015-03-11
    • 2014-06-04
    • 2021-04-14
    • 1970-01-01
    相关资源
    最近更新 更多