为啥 SelectMany 不适用于 EF Core Cosmos DB?

Posted

技术标签:

【中文标题】为啥 SelectMany 不适用于 EF Core Cosmos DB?【英文标题】:Why SelectMany does not work for EF Core Cosmos DB?为什么 SelectMany 不适用于 EF Core Cosmos DB? 【发布时间】:2021-01-11 15:05:33 【问题描述】:

对于 Entity Framework Core Cosmos 提供者,我想要一个类似的查询

SELECT VALUE child
FROM child IN Families.Children
WHERE Families.FamilyName = @familyName

但是执行下面的查询会抛出异常:

var result = _context.Families
   .Where(x => x.FamilyName == familyName)
   .SelectMany(f => f.Children)
   .ToListAsync(ct);
"InvalidOperationException: The LINQ expression 'DbSet<Family>
.Where(f => f.FamilyName == __familyName_0)
.SelectMany(
source: f => EF.Property<IList<Child>>(f, 'Children')
.AsQueryable(),
collectionSelector: (f, c) => new TransparentIdentifier<Family, Child>(
Outer = f,
Inner = c
))' 
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."

为什么表达式被翻译,所以它有明显错误的集合选择器(c,c)

EDIT:它没有错误的集合选择器。似乎将表达式转换为具有以实体的第一个字母命名的参数,当实体被命名为 CapybaraFamily 和 CapybaraChild 时,仍可能会引发其他错误。

但是查询仍然没有被翻译。

实体配置中是否缺少某些内容?

public void Configure(EntityTypeBuilder<Family> builder)

    builder
        .ToContainer("Families")
        .HasNoDiscriminator()
        .HasIndex(x => x.Id)

    builder.OwnsMany(x => x.Children);
        
    builder.Property(x => x.Id).ToJsonProperty("id");

实体:

public class Family : Microsoft.Azure.Documents.Document

    public IList<Child> Children  get; set; 
    public string FamilyName  get; set; 


public class Child

    public string ChildName  get; set; 
    public Guid Id  get; set; 

使用 Microsoft.EntityFrameworkCore,版本=3.1.8.0

【问题讨论】:

【参考方案1】:

不幸的是,您需要在 SelectMany 之前执行 ToList。 Cosmos 有一个底层的文档结构,因此它不能与普通实体一起在 sql 哈希中进行远程缓冲。

SelectMany 之前使用ToList 将首先在本地返回整个集合,但SelectMany 可以在本地工作。

var result = _context.Families
   .Where(x => x.FamilyName == familyName)
   .ToList()
   .SelectMany(f => f.Children);

【讨论】:

以上是关于为啥 SelectMany 不适用于 EF Core Cosmos DB?的主要内容,如果未能解决你的问题,请参考以下文章

EF 自动迁移不适用于虚拟属性

二级缓存 EF codeFirst 和 Predicate 不适用于 where 子句

为啥 UITableViewAutomaticDimension 不适用于 sectionFooterHeight?

为啥排序不适用于矢量?

为啥 MultiBinding 不适用于 CornerRadius

为啥相等检查不适用于数组[重复]