AI エージェント向け: ドキュメントインデックスは https://www.mongodb.com/ja-jp/docs/llms.txt で利用できます。すべてのページの markdown バージョンは、いずれかの URL パスに .md を追加することで利用できます。
Docs Menu

LINQ によるエンティティ データの検索とクエリ

Entity Framework コアを使用すると、データベースコマンドを明示的に実行せずにアプリケーション内のデータを操作できます。 データをクエリするには、 LINQ(言語統合クエリ) 構文を使用します。 LINQ では、C# 固有のキーワードと演算子を使用して、厳密に型指定されたクエリを作成できます。 アプリケーションを実行すると、F Core プロバイダーは LINQ クエリを自動的に変換し、MongoDB Query API を使用してデータベース上で実行します。

このガイドでは、FS コア プロバイダーを使用するように構成されたアプリケーションにおける一般的なクエリ操作の例を確認できます。

Tip

EM コア プロバイダーを使用するようにアプリケーションを構成する方法については、「 EM コア プロバイダーの構成 」を参照してください。

このガイドの例では、 sample_guidesデータベースの planetsコレクションを使用します。このコレクションのドキュメントは、次の Planetクラスをモデルとして使用します。

public class Planet
{
public ObjectId _id { get; set; }
public string name { get; set; } = null!;
public int orderFromSun { get; set; }
public bool hasRings { get; set; }
}

このコレクションは、サンプルデータセットから構成されています。無料のMongoDBクラスターを作成し、このサンプルデータをロードする方法については、クイックスタートガイドを参照してください。

FirstOrDefault()メソッドを使用して 1 つのエンティティを検索するか、 Where()メソッドを使用して複数のエンティティを検索します。

FirstOrDefault()メソッドは、コレクション内で検索条件に一致する最初に見つけたエンティティを返し、一致するエンティティが見つからない場合はnullを返します。

次のコードでは、 Planets FirstOrDefault() nameを使用して、 DBSet

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);
}

A シャドウプロパティは、 .NETエンティティクラスで定義されていないプロパティですが、 Entity Framework モデルに含まれ、データベースのフィールドにマップされます。シャドウ プロパティを使用すると、エンティティのプロパティとして公開せずに、ドキュメント内のデータをクエリまたは追跡できます。

LINQ クエリでシャドウプロパティを参照には、EF.Property<T>() メソッドを呼び出し、構成されたプロパティ名を引数として渡します。ジェネリック型引数は、 シャドウプロパティのデータ型と一致する必要があります。

例、PlanetクラスはmainAtmosphereフィールドのプロパティを定義していません。このフィールドをシャドウプロパティとして構成するには、次の例に示すように、PlanetDbContextOnModelCreating() メソッドで Property<T>() メソッドを呼び出します。

public class PlanetDbContext : DbContext
{
public DbSet<Planet> Planets { get; init; } = null!;
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 値であるかどうかに基づいてドキュメントをクエリできます。

注意

これらのメソッドは、Real プロパティと シャドウ プロパティの両方で機能します。

Mql.Exists() メソッドは、フィールド値が null であるドキュメントを含む、指定されたフィールドを含むドキュメントを照合します。

次のコードでは、Mql.Exists() メソッドを使用して、hasRingsフィールドを持つすべての惑星を検索し、惑星名をコンソールに出力します。

var planetNames = db.Planets
.Where(p => Mql.Exists(p.hasRings))
.Select(p => p.name);
foreach (var name in planetNames)
{
Console.WriteLine(name);
}

Mql.IsMissing() メソッドは、指定されたフィールドを含まないドキュメントを一致させます。

次のコードでは、Mql.IsMissing() メソッドを使用して、hasRingsフィールドがないすべての惑星を検索し、惑星名をコンソールに出力します。

var planetNames = db.Planets
.Where(p => Mql.IsMissing(p.hasRings))
.Select(p => p.name);
foreach (var name in planetNames)
{
Console.WriteLine(name);
}

Mql.IsNullOrMissing() メソッドは、指定されたフィールドが欠落しているか、null 値があるドキュメントに一致します。

次のコードでは、Mql.IsNullOrMissing() メソッドを使用して、hasRingsフィールドが欠落しているか null であるすべての惑星を検索し、惑星名をコンソールに出力します。

var planetNames = db.Planets
.Where(p => Mql.IsNullOrMissing(p.hasRings))
.Select(p => p.name);
foreach (var name in planetNames)
{
Console.WriteLine(name);
}

クエリからエンティティを返す順序を指定するには、 OrderBy()メソッドを使用します。 OrderBy()は、指定された並べ替え条件に基づいて要素を昇順で並べ替えます。

次のコードでは、 OrderBy()メソッドを使用してすべての惑星を検索し、 orderFromSunフィールドの値で昇順に並べ替えます。 次に、結果をコンソールに出力します。

var planetList = db.Planets.OrderBy(p => p.orderFromSun);
foreach (var p in planetList)
{
Console.WriteLine(p.name);
}
{"_id":"...","name":"Mercury","orderFromSun":1,"hasRings":false}
{"_id":"...","name":"Venus","orderFromSun":2,"hasRings":false}
{"_id":"...","name":"Earth","orderFromSun":3,"hasRings":false}
{"_id":"...","name":"Mars","orderFromSun":4,"hasRings":false}
{"_id":"...","name":"Jupiter","orderFromSun":5,"hasRings":true}
{"_id":"...","name":"Saturn","orderFromSun":6,"hasRings":true}
{"_id":"...","name":"Uranus","orderFromSun":7,"hasRings":true}
{"_id":"...","name":"Neptune","orderFromSun":8,"hasRings":true}

Tip

降順でソート

OrderByDescending()メソッドを使用して、クエリの結果を降順で並べ替えることができます。

ThenBy()メソッドを使用して、クエリで 2 次並べ替えを実行できます。 ThenBy()メソッドは、指定された並べ替え条件に基づいて、 OrderBy()メソッドの結果を昇順で並べ替えます。 ThenBy()メソッドはOrderBy()メソッドに連結する必要があります。

Tip

降順での二次ソート

ThenByDescending()メソッドを使用して、降順で二次並べ替えを実行できます。

次のコードでは、 OrderBy()メソッドとThenBy()メソッドを使用してすべての惑星を検索し、 hasRings()フィールドで並べ替え、 nameフィールドで 2 次並べ替えます。

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);
}
{"_id":"...","name":"Earth","orderFromSun":3,"hasRings":false}
{"_id":"...","name":"Mars","orderFromSun":4,"hasRings":false}
{"_id":"...","name":"Mercury","orderFromSun":1,"hasRings":false}
{"_id":"...","name":"Venus","orderFromSun":2,"hasRings":false}
{"_id":"...","name":"Jupiter","orderFromSun":5,"hasRings":true}
{"_id":"...","name":"Neptune","orderFromSun":8,"hasRings":true}
{"_id":"...","name":"Saturn","orderFromSun":6,"hasRings":true}
{"_id":"...","name":"Uranus","orderFromSun":7,"hasRings":true}

Tip

ブール値を持つフィールドでソートすると、フィールド値がfalse のエンティティがtrue のフィールド値より前に表示されます。

Take() メソッドを使用して、クエリから返すエンティティの最大数を指定します。

次のコードは、Take() メソッドを使用して、Planets コレクションから最初の 3 個の惑星を返します。

var planetList = db.Planets.Take(3);
foreach (var p in planetList)
{
Console.WriteLine(p.name);
}

Skip() メソッドを使用して、クエリから結果を返す前にスキップするエンティティの数を指定します。

次のコードでは、OrderBy() メソッドと Skip() メソッドを使用して、最初の 5 個の惑星(orderFromSun でソート)をスキップし、残りの惑星を返します。

var planetList = db.Planets.OrderBy(p => p.orderFromSun).Skip(5);
foreach (var p in planetList)
{
Console.WriteLine(p.name);
}

FS コア プロバイダーは、次のスカラー集計メソッドをサポートしています。

  • Count():コレクション内の要素の数または述語に一致するドキュメントの数を返します

  • LongCount():コレクション内の要素の数を long として返すか、述語に一致するドキュメントの数を返します

  • Any():コレクション内のいずれかの要素が述語に一致する場合は true を返します

  • Max():コレクション内の指定されたフィールドの最大値を返します

  • Min():コレクション内の指定されたフィールドの最小値を返します

  • Sum():コレクション内の指定されたフィールドの値の合計を返します

  • Average():コレクション内の指定されたフィールドの値の平均を返します

次のセクションでは、前述の各方法の例を示します。

次の例では、Count() メソッドを使用して、Planetsコレクション内の要素の数をカウントします。

var planetCount = db.Planets.Count();
Console.WriteLine("Planet Count: " + planetCount);

次の例では、Count() メソッドを使用して、hasRingsフィールドが true に設定されている Planetsコレクション内の要素の数をカウントします。

var planetCountWithRings = db.Planets.Count(p => p.hasRings);
Console.WriteLine("Planet Count with Rings: " + planetCountWithRings);

次の例では、LongCount() メソッドを使用して Planetsコレクション内の要素の数をカウントし、その結果を long として返します。

var planetCountLong = db.Planets.LongCount();
Console.WriteLine("Long Planet Count: " + planetCountLong);

次の例では、LongCount() メソッドを使用して、hasRingsフィールドが true に設定されている Planetsコレクション内の要素の数をカウントし、その結果を long として返します。

var planetCountLongWithRings = db.Planets.LongCount(p => p.hasRings);
Console.WriteLine("Long Planet Count with Rings: " + planetCountLongWithRings);

次の例では、Any() メソッドを使用して、Planetsコレクション内のいずれかの要素で hasRingsフィールドが true に設定されているかどうかを確認します。

var results = db.Planets.Any(p => p.hasRings);
Console.WriteLine("Planet with Rings: " + results);

次の例では、Max() メソッドを使用して、Planetsコレクション内の orderFromSunフィールドの最大値を検索します。

var furthestPlanet = db.Planets.Max(p => p.orderFromSun);
Console.WriteLine("Furthest Planet: " + furthestPlanet);

次の例では、Min() メソッドを使用して、Planetsコレクション内の orderFromSunフィールドの最小値を検索します。

var closestPlanet = db.Planets.Min(p => p.orderFromSun);
Console.WriteLine("Closest Planet: " + closestPlanet);

次の例では、Sum() メソッドを使用して、Planetsコレクション内の orderFromSunフィールドの合計を求めます。

var totalOrderFromSun = db.Planets.Sum(p => p.orderFromSun);
Console.WriteLine("Total Order From Sun: " + totalOrderFromSun);

次の例では、Average() メソッドを使用して、Planetsコレクション内の orderFromSunフィールドの平均値を検索します。

var averageOrderFromSun = db.Planets.Average(p => p.orderFromSun);
Console.WriteLine("Average Order From Sun: " + averageOrderFromSun);

LINQ クエリを書いた後、生成されたクエリを調査して、プロバイダーが予想される形状を MongoDB Server に送信していることを確認します。開発中にクエリを調査するには、LogTo() メソッドを使用して、DbContext で EF Core ログ記録を有効にします。

次の例は、DbContext オブジェクトの作成時にコンソールへのログ記録を有効にする方法を示しています。

var mongoClient = new MongoClient("<connection string URI>");
var dbContextOptions =
new DbContextOptionsBuilder<MyDbContext>()
.UseMongoDB(mongoClient, "sample_guides")
.LogTo(Console.WriteLine)
.Options;
var db = new MyDbContext(dbContextOptions);

プロバイダーは機密データログが有効になっている場合にのみ、完全な MQL クエリテキストをログに記録します。機密データログを有効にしない場合、クエリログに値が記録されない場合があります。機密データログを有効にするには、次の例に示すように、DbContextOptionsBuilderオブジェクトからEnableSensitiveDataLogging()メソッドを呼び出します。

var mongoClient = new MongoClient("<connection string URI>");
var dbContextOptions =
new DbContextOptionsBuilder<MyDbContext>()
.UseMongoDB(mongoClient, "sample_guides")
.LogTo(Console.WriteLine)
.EnableSensitiveDataLogging()
.Options;
var db = new MyDbContext(dbContextOptions);

重要

本番環境での使用は避けてください

機密データのログ記録は開発環境のみで有効にします。

MongoClient でカメルケースのフィールド名付けなどのカスタム BSON 直列化規約を登録すると、これらの規約によって MongoDB に保存されるフィールド名がエンティティモデルのプロパティ名と異なる場合があります。EF Core プロバイダー はエンティティプロパティ名を使用して MQL を生成するため、不一があると、クエリのターゲットが間違ったフィールドになり、そのフィールドのインデックスがバイパスされる可能性があります。保存されたフィールド名がエンティティプロパティ名と異なる場合は、次の例に示すように、 HasElementName() を使用してプロパティを OnModelCreating() の保存されたフィールド名に明示的にマップできます。

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.Entity<Planet>()
.Property(p => p.name)
.HasElementName("name");
}

Tip

.NET/C# ドライバーのモニタリング API

MongoDBコマンドに対する下位レベルの可視性が必要な場合は、MongoClientオブジェクトで.NET/C# ドライバーモニタリングAPIを使用できます。これらのAPIの詳細については、.NET/C# Driverドキュメントの「モニタリング」を参照してください。

MongoDBの集計の詳細については、 MongoDB Serverマニュアルの 集計操作ガイドを参照してください。

このガイドで説明されている EF Core メソッドの詳細については、次の .NET API ドキュメントへのリンクを参照してください。

このページで使用されている .NET/C# ドライバー メソッドについて詳しくは、次の API ドキュメントのリンクを参照してください。

HasElementName() メソッドの詳細については、次の EF Core プロバイダー API ドキュメントリンクを参照してください。