首页 > 解决方案 > 具有可选导航属性的嵌套 DTO:“在类型 'Expression[]' 和匿名类型之间未定义强制运算符”

问题描述

我正在尝试使用导航属性构建带有实体框架(6.2.0)的嵌套 DTO。导航属性是可选的,因此我需要以 DTO 的相应属性也为 null 的方式处理 null 值:

var result = db.Projects.Select(
    p => new
    {
        p.Id,
        Notifications = p.Notifications
            .Where(n => n.ContactId == user.Id)
            .Select(a => new
            {
                a.Id,
                a.ContactId,
                Candidate = a.Candidate == null ? null : new
                {
                    a.Candidate.Id,
                    a.Candidate.LastName
                }
            })
            .OrderByDescending(n => n.Timestamp)

    })
    .FirstOrDefault(p => p.Id == projectId);

如代码所示,在我的模型中,有Project0-n 的实体Notifications,其中 aNotification可以选择有一个Candidate

上面的代码抛出:

System.InvalidOperationException:'没有强制运算符在类型'System.Linq.Expressions.Expression[]'和'<>f__AnonymousType43`2[System.Int32,System.String]'之间定义。

在运行时。如果我像这样删除空检查

Candidate = new
{
   a.Candidate.Id,
   a.Candidate.LastName
}

Candidate当属性为空时,它预期会引发异常。Null 传播也不起作用,而且 - 即使它起作用了 - 也不符合 DTO 属性Candidate应该为 null 而不是具有 null 属性值的对象的要求:

Candidate = new
{
   Id = a.Candidate?.Id,
   LastName = a.Candidate?.LastName
}

这不会编译:

表达式树 lambda 可能不包含空传播运算符。

作为参考,导航属性的定义:

modelBuilder.Entity<Project>(entity =>
{
    // ...

    entity.HasMany(p => p.Notifications)
        .WithOne(a => a.Project)
        .HasForeignKey(a => a.ProjectId)
        .IsRequired(false)
        .OnDelete(DeleteBehavior.Cascade);

});

modelBuilder.Entity<Notification>(entity =>
{  
    // ...
 
    entity.HasOne(e => e.Candidate)
        .WithMany(c => c.Notifications)
        .HasForeignKey(e => e.CandidateId)
        .HasPrincipalKey(e => e.Guid)
        .IsRequired(false)
        .OnDelete(DeleteBehavior.SetNull);
});

标签: c#entity-frameworknavigation-properties

解决方案


推荐阅读