Overview
Entity Framework Core 允许您在不显式运行数据库命令的情况下处理应用程序中的数据。 要查询数据,请使用语言集成查询 (LINQ) 语法。 LINQ 允许使用特定于 C# 的关键字和操作符写入强类型查询。 运行应用程序时,EF Core 提供程序会自动转换 LINQ 查询,并使用MongoDB查询API在数据库上运行这些查询。
在本指南中,您可以查看配置为使用 EF Core 提供程序的应用程序的常见查询操作示例。
提示
要学习;了解如何配置应用程序以使用 EF Core 提供程序,请参阅配置 EF Core 提供程序。
样本数据
本指南中的示例使用 sample_guides数据库中的 planets集合。此集合中的文档使用以下 Planet 类作为模型:
public class Planet { public ObjectId _id { get; set; } public string name { get; set; } public int orderFromSun { get; set; } public bool hasRings { get; set; } }
此集合来自Atlas提供的 示例数据集。请参阅快速入门指南,学习;了解如何创建免费的MongoDB 集群并加载此示例数据。
查找实体
使用FirstOrDefault()方法查找单个实体,或使用Where()方法查找多个实体。
查找单个实体
FirstOrDefault()方法返回在collection中找到的与搜索条件匹配的第一个实体;如果未找到匹配的实体,则返回null 。
以下代码使用FirstOrDefault()方法从名为Planets的DBSet中查找name字段为 "Mercury" 的行星,并将行星名称打印到控制台:
var planet = db.Planets.FirstOrDefault(p => p.name == "Mercury"); Console.WriteLine(planet.name);
查找多个实体
您可以使用Where()方法从集合中检索多个实体。 Where()返回所有符合搜索条件的实体。
以下代码使用Where()方法查找hasRings字段设置为true的所有行星,并将行星名称打印到控制台。
var planets = db.Planets.Where(p => p.hasRings); foreach (var p in planets) { Console.WriteLine(p.name); }
查询影子属性
影子属性是指未在 .NET 实体类上定义,但包含在实体框架模型中并映射到数据库字段的属性。您可以使用影子属性来查询或追踪文档中的数据,而无需将其公开为实体上的属性。
要在 LINQ查询中引用影子属性,请调用 EF.Property<T>() 方法并将配置的属性名称作为参数传递。泛型类型参数必须与影子属性的数据类型匹配。
示例,Planet 类没有为 mainAtmosphere字段定义属性。要将此字段配置为影子属性,请调用 PlanetDbContext 的 OnModelCreating() 方法中的 Property<T>() 方法,如以下示例所示:
public class PlanetDbContext : DbContext { public DbSet<Planet> Planets { get; init; } public static PlanetDbContext Create(IMongoDatabase database) => new(new DbContextOptionsBuilder<PlanetDbContext>() .UseMongoDB(database.Client, database.DatabaseNamespace.DatabaseName) .Options); public PlanetDbContext(DbContextOptions options) : base(options) { } protected override void OnModelCreating(ModelBuilder modelBuilder) { base.OnModelCreating(modelBuilder); modelBuilder.Entity<Planet>().ToCollection("planets"); modelBuilder.Entity<Planet>().Property<string[]>("mainAtmosphere"); } }
对 modelBuilder.Entity<Planet>().Property<string[]>("mainAtmosphere") 的调用指示框架在模型中包含 mainAtmosphere 并将其映射到MongoDB中的 string[]字段。
以下代码使用 EF.Property<string[]>() 方法查找所有具有非空 mainAtmosphere 影子属性的行星,并将行星名称打印到控制台:
var planets = db.Planets.Where( p => EF.Property<string[]>(p, "mainAtmosphere").Length > 0); foreach (var p in planets) { Console.WriteLine(p.name); }
检查字段存在性
您可以使用 Mql 类中的方法,根据字段是否存在、是否缺失或是否具有 null 值查询文档。
注意
这些方法既适用于实际属性,也适用于影子属性。
Mql.Exists
Mql.Exists() 方法匹配包含指定字段的文档,包括字段值为 null 的文档。
以下代码使用 Mql.Exists() 方法查找具有 hasRings字段的所有行星并将行星名称打印到控制台:
var planets = db.Planets.Where(p => Mql.Exists(p.hasRings)); foreach (var p in planets) { Console.WriteLine(p.name); }
Mql.IsMissing
Mql.IsMissing() 方法匹配不包含指定字段的文档。
以下代码使用 Mql.IsMissing() 方法查找所有没有 hasRings字段的行星,并将行星名称打印到控制台:
var planets = db.Planets.Where(p => Mql.IsMissing(p.hasRings)); foreach (var p in planets) { Console.WriteLine(p.name); }
Mql.IsNullOrMissing
Mql.IsNullOrMissing() 方法匹配指定字段缺失或具有 null 值的文档。
以下代码使用 Mql.IsNullOrMissing() 方法查找缺少 hasRings字段或 null 的所有行星,并将行星名称打印到控制台:
var planets = db.Planets.Where(p => Mql.IsNullOrMissing(p.hasRings)); foreach (var p in planets) { Console.WriteLine(p.name); }
对实体进行排序
使用OrderBy()方法指定从查询中返回实体的顺序。 OrderBy()根据指定的排序条件按升序对元素进行排序。
以下代码使用OrderBy()方法查找所有行星,并按orderFromSun字段的值升序对它们进行排序。 然后,它将结果打印到控制台。
var planetList = db.Planets.OrderBy(p => p.orderFromSun); foreach (var p in planetList) { Console.WriteLine(p.name); }
Mercury Venus Earth Mars Jupiter Saturn Uranus Neptune
提示
按降序排序
您可以使用OrderByDescending()方法按降序对查询结果进行排序。
您可以使用ThenBy()方法对查询执行二级排序。 ThenBy()方法根据指定的排序条件对OrderBy()方法的结果进行升序排序。 ThenBy()方法应链接到OrderBy()方法。
提示
按降序进行二级排序
您可以使用ThenByDescending()方法按降序执行二级排序。
以下代码使用OrderBy()和ThenBy()方法查找所有行星,并按hasRings()字段对它们进行排序,并在name字段上进行辅助排序。
var planetList = db.Planets.OrderBy(o => o.hasRings).ThenBy(o => o.name); foreach (var p in planetList) { Console.WriteLine("Has rings: " + p.hasRings + ", Name: " + p.name); }
Has rings: False, Name: Earth Has rings: False, Name: Mars Has rings: False, Name: Mercury Has rings: False, Name: Venus Has rings: True, Name: Jupiter Has rings: True, Name: Neptune Has rings: True, Name: Saturn Has rings: True, Name: Uranus
提示
对具有布尔值的字段进行排序时,字段值为false的实体显示在值为true的实体之前。
标量聚合
EF Core 提供程序支持以下标量聚合方法:
Count():返回集合中与谓词匹配的元素数或文档数LongCount():以long的形式返回集合中的元素数量,或与谓词匹配的文档数量Any():如果集合中的任何元素与谓词匹配,则返回trueMax():返回集合中指定字段的最大值Min():返回集合中指定字段的最小值Sum():返回集合中指定字段的值的总和Average():返回集合中指定字段值的平均值
以下部分举例说明了上述每种方法。
数数
以下示例使用 Count() 方法计算 Planets集合中元素的数量:
var planetCount = db.Planets.Count(); Console.WriteLine("Planet Count: " + planetCount);
以下示例使用 Count() 方法计算 Planets集合中 hasRings字段设立为 true 的元素数量:
var planetCountWithRings = db.Planets.Count(p => p.hasRings); Console.WriteLine("Planet Count with Rings: " + planetCountWithRings);
LongCount
以下示例使用 LongCount() 方法计算 Planets集合中元素的数量,并将结果作为 long 返回:
var planetCountLong = db.Planets.LongCount(); Console.WriteLine("Long Planet Count: " + longCount);
以下示例使用 LongCount() 方法计算 Planets集合中 hasRings字段设立为 true 的元素数量,并将结果作为 long 返回:
var planetCountLongWithRings = db.Planets.LongCount(p => p.hasRings); Console.WriteLine("Long Planet Count with Rings: " + planetCountLongWithRings);
Any
以下示例使用 Any() 方法检查 Planets集合中是否有元素将 hasRings字段设立为 true:
var results = db.Planets.Any(p => p.hasRings); foreach (var p in results) { Console.WriteLine("Planet with Rings: " + p.name); }
Max
以下示例使用 Max() 方法查找 Planets集合中 orderFromSun字段的最大值:
var furthestPlanet = db.Planets.Max(p => p.orderFromSun); Console.WriteLine("Furthest Planet: " + furthestPlanet.name);
Min
以下示例使用 Min() 方法查找 Planets集合中 orderFromSun字段的最小值:
var closestPlanet = db.Planets.Min(p => p.OrderFromSun); Console.WriteLine("Closest Planet: " + closestPlanet.Name);
总和
以下示例使用 Sum() 方法计算 Planets集合中 mass字段的总和:
var totalMass = db.Planets.Sum(p => p.mass); Console.WriteLine("Total Mass of Planets: " + totalMass);
平均值
以下示例使用 Average() 方法查找 Planets集合中 mass字段的平均值:
var averageMass = db.Planets.Average(p => p.mass); Console.WriteLine("Average Mass of Planets: " + averageMass);
更多信息
要学习;了解有关MongoDB中聚合的更多信息,请参阅MongoDB Server手册中的聚合操作指南。
要进一步了解本指南中讨论的方法,请参阅以下 .NET API 文档链接:
要学习了解有关 Mql 类方法的详情,请参阅以下 .NET/C# 驱动程序 API 文档链接: