微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

搜索预计的EF核心导航属性

如何解决搜索预计的EF核心导航属性

使用EF Core 3.1,我试图在将其投影为其他类型后,对可为空的导航属性(也称为左联接)执行搜索

例如:

var dtos = await query
    .Select(x => new RootEntityDto
    {
        // ...

        nested = x.nestedId.HasValue
            ? new nestedEntityDto
            {
                // ...

                Description = x.nested.Description
            }
            : null
    })
    .Where(x => x.nested.Description.Contains("2"))
    .ToArrayAsync();

问题是,它给我一个元组错误,可能有条件地导致null:

The LINQ expression 'DbSet<RootEntity>
    .LeftJoin(
        outer: DbSet<nestedEntity>,inner: f => EF.Property<Nullable<int>>(f,"nestedId"),outerKeySelector: o => EF.Property<Nullable<int>>(o,"Id"),innerKeySelector: (o,i) => new TransparentIdentifier<RootEntity,nestedEntity>(
            Outer = o,Inner = i
        ))
    .Where(f => EF.Property<Nullable<int>>(f.Inner,"Id") != null ? new nestedEntityDto{ 
        Description = f.Inner.Description,}
     : null.Description.Contains("2"))' Could not be translated. Either rewrite the query in a form that can be translated,or switch to client evaluation explicitly by inserting a call to either AsEnumerable(),AsAsyncEnumerable(),ToList(),or ToListAsync(). See https://go.microsoft.com/fwlink/?linkid=2101038 for more information.

如果在将实体投影到DTO之前尝试完全相同的操作,那么我没有问题:

var entities = await query
    .Where(x => x.nested.Description.Contains("2"))
    .ToArrayAsync();

我知道简单的解决方案是在投影发生之前执行Where语句,但这不是一种选择。为了说明本发明的目的,简化了上述示例。我也不会对评估客户端查询感兴趣,因为我不知道三元查询的更好选择。

理想情况下,我只是在寻找有条件地投影左联接导航属性的最佳实践,以便仍可以对其进行搜索

编辑:我决定尝试使用AutoMapper 10.1.1并收到类似的错误

var dtos = await query
    .ProjectTo<RootEntityDto>(_mapper.ConfigurationProvider,x => x.nested)
    .Where(x => x.nested.Description.Contains("2"))
    .ToArrayAsync();
The LINQ expression 'DbSet<RootEntity>
    .LeftJoin(
        outer: DbSet<nestedEntity>,"Id") == null ? null : new nestedEntityDto{ 
        Description = f.Inner.Description
    }
    .Description.Contains("2"))' Could not be translated. Either rewrite the query in a form that can be translated,or ToListAsync(). See https://go.microsoft.com/fwlink/?linkid=2101038 for more information.

解决方法

EF Core 3完全改变了查询的评估方式,并且不支持所有查询构造。我怀疑在DTO投影之后尝试进行过滤是这里的根本问题。您能否通过此查询测试升级到EF Core 5的情况,并查看它是否仍然失败以及5支持更多查询模式。

,

我对AutoMapper的工作进行了一些研究,发现了一个有效的约定:

var dtos = await query
    .Select(x => new RootEntityDto
    {
        // ...

        Nested = x.Nested == null
            ? null
            : new NestedEntityDto
            {
                // ...

                Description = x.Nested.Description
            }
    })
    .Where(x => x.Nested.Description.Contains("2"))
    .ToArrayAsync();

注意,我反转了三元数并将切换为!x.NestedId.HasValuex.Nested == null。但是即使进行了这些更改,我仍然必须升级到EF Core 5。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。