EF Core对接Cosmos DB实现Distinct计数及自定义返回类型咨询
EF Core Cosmos DB 去重计数解决方案
方案1:使用无键实体类型兼容低版本EF Core
EF Core 3.0及以上版本支持无键实体类型,可用来接收原生SQL返回的非DbSet对应结构的结果,步骤如下:
- 定义接收计数结果的简单类
public class CountResult { public int Count { get; set; } }
- 在DbContext的
OnModelCreating方法中注册无键实体,指定对应的Cosmos容器名
protected override void OnModelCreating(ModelBuilder modelBuilder) { modelBuilder.Entity<CountResult>() .HasNoKey() .ToContainer("你实际查询的容器名称"); }
- 执行原生SQL获取结果
var distinctStoreIdCount = context.Set<CountResult>() .FromSqlRaw("select value count(1) as Count from (SELECT distinct c.StoreId FROM c)") .First() .Count;
注意:SQL中返回的字段别名需要和定义的类属性名完全匹配,否则会映射失败。
方案2:直接调用Cosmos原生SDK查询
不需要额外定义实体,直接从EF Core上下文中获取Cosmos客户端执行查询,适合所有EF Core版本:
using Microsoft.EntityFrameworkCore; using Microsoft.Azure.Cosmos; // 从EF Core上下文获取Cosmos原生客户端 var cosmosClient = context.Database.GetCosmosClient(); var container = cosmosClient.GetDatabase("你的Cosmos数据库名").GetContainer("你查询的容器名"); // 构造查询语句 var query = new QueryDefinition("select value count(1) from (SELECT distinct c.StoreId FROM c)"); var iterator = container.GetItemQueryIterator<int>(query); int count = 0; while (iterator.HasMoreResults) { var result = await iterator.ReadNextAsync(); count = result.FirstOrDefault(); }
方案3:高版本EF Core原生支持
- 如果你使用的是EF Core 7.0及以上版本,
Distinct().Count()的LINQ写法已经被官方支持,可直接写LINQ语句无需手动写SQL:
var distinctCount = await context.你的实体集合 .Select(x => x.StoreId) .Distinct() .CountAsync();
- 如果你使用的是EF Core 8.0及以上版本,还可以直接用
SqlQuery方法返回标量类型,不需要定义无键实体也不需要注册:
var distinctCount = await context.Database .SqlQuery<int>($"select value count(1) from (SELECT distinct c.StoreId FROM c)") .FirstAsync();
关于EF Core是否支持返回自定义原始类型的说明
支持,EF Core 3.0+可通过无键实体类型实现,EF Core 8.0+已经原生支持直接返回标量/自定义类型的原始SQL查询结果,不需要绑定到已注册的DbSet实体。
内容的提问来源于stack exchange,提问作者yaxizhang
相关产品推荐
相关产品推荐

