Docs Menu
Docs Home
/ / /
C#/.NET ドライバー
/ /

クラスマッピング

このガイドでは、MongoDB .NET/C# ドライバーで BSON ドキュメントと C# クラス間のマッピングをカスタマイズする方法を学習できます。デフォルトのクラスマッピング動作の詳細を確認したり、ドライバーでデータを直列化または逆直列化する方法をカスタマイズしたりする必要がある場合にお読みください。

POCO 属性を使用して直列化の動作を設定することもできます。詳しくは、 POCOガイドをご覧ください。

MongoDB コレクション内のデータを表すために、 BsonDocument ではなくクラスを使用すると、.NET/C# ドライバーは、データの直列化または逆直列化に使用するクラス マップを自動的に作成します。このマッピングは、ドキュメント内のフィールドの名前をクラス内のプロパティの名前と照合することで行われます。

重要

クラス内のプロパティの型は、ドキュメント内のフィールドの型と一致する必要があります。.NET/C# ドライバーは、クラス内のプロパティの型に基づいてシリアライザーをインスタンス化します。ドライバーがデータを逆直列化しようとしたときに型が一致しない場合、シリアライザーは例外をスローします。

ドライバーの自動クラスマッピング機能をバイパスし、RegisterClassMap() メソッドを使用してクラス マップを手動で定義できます。

次の例では、Person クラスを定義しています。

public class Person
{
public string Name { get; set; }
public int Age { get; set; }
public List<string> Hobbies {get; set;}
}

次のコードは、 Person クラスのクラス マップを登録する方法を示しています。

BsonClassMap.RegisterClassMap<Person>(classMap =>
{
classMap.MapMember(p => p.Name);
classMap.MapMember(p => p.Age);
classMap.MapMember(p => p.Hobbies);
});

重要

クラスマップを登録する場合

クラス マップはコードで必要になる前に登録する必要があります。MongoDB との接続を初期化する前に、クラス マップを登録することをお勧めします。

ドライバーで残りのプロパティを自動的にマッピングできるようにしながら、クラス プロパティのサブセットを手動でマッピングすることもできます。それには、クラス マップを登録して AutoMap() メソッドを呼び出してから、プロパティを手動で指定します。

次のコード例では、 AutoMap() メソッドが Person クラスのすべてのプロパティをマッピングし、 Hobbies フィールドのマッピングを手動で調整します。

BsonClassMap.RegisterClassMap<Person>(classMap =>
{
classMap.AutoMap();
classMap.MapMember(p => p.Hobbies).SetElementName("favorite_hobbies");
});

クラスに属性を適用するか、クラスマップの登録時にメソッドを呼び出すことで、ドライバーがクラスレベルでドキュメントを直列化および逆直列化する方法をカスタマイズできます。

クラスマップを登録する際に UnmapMember() メソッドを使用することで、指定されたフィールドが直列化されないようにすることができます。

次の例では、Ageプロパティが直列化されないようにクラスマップを作成する方法を示しています。

BsonClassMap.RegisterClassMap<Person>(classMap =>
{
classMap.AutoMap();
classMap.UnmapMember(p => p.Age);
});

Tip

フィールド属性を使用してこの動作を設定する方法については、POCO ガイドの「フィールドを省略する」セクションを参照してください。

BSON ドキュメントが C# クラスに逆直列化されると、.NET/C# ドライバーはドキュメント内の各フィールドの名前を調べ、クラス内の一致するプロパティ名を見つけようとします。デフォルトでは、ドキュメント内のフィールドがクラス内で一致しない場合、ドライバーは例外をスローします。

BsonIgnoreExtraElements 属性を使用すると、一致するクラス プロパティを持たない要素を無視することができます。そうすると、ドライバーが例外をスローすることがなくなり、一致するクラス プロパティを持つ他のフィールドがマッピングされます。

次の例では、クラスに BsonIgnoreExtraElements 属性を追加する方法を示しています。

[BsonIgnoreExtraElements]
public class Person
{
public string Name { get; set; }
public int Age { get; set; }
public List<string> Hobbies {get; set;}
}

クラス マップを登録するときに余計な要素を無視することもできます。

BsonClassMap.RegisterClassMap<Person>(classMap =>
{
classMap.AutoMap();
classMap.SetIgnoreExtraElements(true);
});

デフォルトでは、ドライバーは Idid、または _id という名前のパブリック プロパティを BSONの _id フィールドにマッピングします。_idフィールドにマップするプロパティを明示的に選択するには、 MapIdMember()クラス マップ メソッドを使用します。

次のコード例は、Identifier プロパティを _id フィールドにマッピングします。

BsonClassMap.RegisterClassMap<Person>(classMap =>
{
classMap.AutoMap();
classMap.MapIdMember(p => p.Identifier);
});

ドキュメントIDを表すために文字列を使用している場合は、IdMemberMap.SetSerializer() クラス マップ メソッドを使用して、これらの値を MongoDB の ObjectId インスタンスにシリアライズできます。このようにして、データベースでの MongoDB の ID 管理におけるベストプラクティスに従いながら、アプリケーション内で ID 値の表現方法をカスタマイズすることができます。

次の例では、ドライバーに文字列 ID 値を ObjectId 値としてシリアル化するよう指示します。

BsonClassMap.RegisterClassMap<Person>(classMap =>
{
classMap.AutoMap();
classMap.IdMemberMap.SetSerializer(new StringSerializer(BsonType.ObjectId));
});

ドライバーに 24 桁の有効な 16 進文字列を ID 値として生成させたい場合は、SetIdGenerator() メソッドを MapIdMember() メソッドにチェーンし、StringObjectIdGenerator のインスタンスを渡すことができます。

BsonClassMap.RegisterClassMap<Person>(classMap =>
{
classMap.AutoMap();
classMap.MapIdMember(p => p.Identifier).SetIdGenerator(StringObjectIdGenerator.Instance);
});

ID ジェネレータの詳細については、POCOs ガイドの「ID ジェネレータを指定」セクションを参照してください。

アプリケーションがドキュメント内で一意の識別子として GUID を使用する場合、クラスマップを登録して Guid 値の直列化方法を指定することができます。デフォルトでは、ドライバーは GuidGenerator 型を使用して ID プロパティの一意の値を生成します。GUID 表現を指定するには、GuidSerializer を初期化する必要があります。

次のコードでは、クラスマップを登録するときに Standard GUID 表現を指定します。

BsonClassMap.RegisterClassMap<Person>(classMap =>
{
classMap.AutoMap();
classMap.IdMemberMap.SetSerializer(new GuidSerializer(GuidRepresentation.Standard));
});

GUID の直列化の詳細については、GUIDガイド を参照してください。

デフォルトでは、.NET/C# ドライバーは、クラスに引数のないコンストラクタがある場合にのみ、クラスを自動的にマッピングできます。1 つ以上の引数を受け入れるコンストラクタをドライバーで使用したい場合は、BsonConstructor 属性をコンストラクタに追加できます。この場合はドライバーで型が分析され、コンストラクタの引数をクラスのプロパティまたはフィールドにマッピングする方法が決定されます。

ドライバーは、次の Person クラスのクラス マップを作成する際、 BsonConstructor 属性でマークされたコンストラクターを使用します。name 引数は Name プロパティにマッピングされ、age 引数は Age プロパティにマッピングされます。

public class Person
{
public string Name { get; set; }
public int Age { get; set; }
public List<string> Hobbies {get; set;}
[BsonConstructor]
public Person(string name, string age)
{
Name = name;
Age = age;
}
}

Tip

複数の BsonConstructor 属性

BsonConstructor 属性を持つコンストラクターが複数ある場合、ドライバーはドキュメント内のフィールドと一致するパラメーターが最も多いコンストラクターを使用します。

クラス マップの登録時に使用するコンストラクタを指定することもできます。

public class Person
{
public string Name { get; set; }
public int Age { get; set; }
public List<string> Hobbies {get; set;}
public Person(string name, string age)
{
Name = name;
Age = age;
}
}
BsonClassMap.RegisterClassMap<Person>(classMap =>
{
classMap.AutoMap();
classMap.MapCreator(p => new Person(p.Name, p.Age));
});

プロパティに属性を追加することで、ドライバーがクラス プロパティを直列化する方法もカスタマイズできます。カスタム プロパティの直列化の詳細については、 「カスタム直列化」を参照してください。

一致するクラス プロパティを持たない、ドキュメント内の余計な要素を格納するように C# クラスを設計できます。それには、クラスに余計な要素を保持するためのBsonDocument 型プロパティが必要です。

次のコードでは、 BsonExtraElements 属性と ExtraElements プロパティを使用して、ドライバーに余計な要素を格納するように指示します。

public class Person
{
public string Name { get; set;
public int Age { get; set; }
public List<string> Hobbies {get; set;}
[BsonExtraElements]
public BsonDocument ExtraElements {get; set;}
}

次のようにクラス マップを初期化するときに、余計な要素をサポートすることもできます。

BsonClassMap.RegisterClassMap<Person>(classMap =>
{
classMap.AutoMap();
classMap.MapExtraElementsMember(p => p.ExtraElements);
});

注意

ドライバーが余計な要素を含むクラスを BSON に直列化した後、余計な要素は元のドキュメントと同じ順序にならない場合があります。

メソッドを使用して、プロパティを直列化するかどうかを決定できます。直列化の際にドライバーによってメソッドが自動的に使われるようにするには、メソッド名の前に ShouldSerialize を付け、その後にメソッドが適用されるプロパティの名前を付ける必要があります。ドライバーは、この命名規則を持つメソッドを検出すると、そのメソッドを使用して、指定されたプロパティ名を持つプロパティを直列化するかどうかを決定します。

次の例では、Age プロパティの値が 0 でない場合にだけ同プロパティを直列化するメソッドを作成します。値がこの要件を満たさないプロパティは直列化されません。

public class Person
{
public string Name { get; set; }
public int Age { get; set; }
public List<string> Hobbies {get; set;}
public bool ShouldSerializeAge()
{
return Age != 0;
}
}

クラス マップの登録時にメソッドを指定することもできます。

BsonClassMap.RegisterClassMap<Employee>(classMap =>
{
classMap.AutoMap();
classMap.MapMember(p => c.Age).SetShouldSerializeMethod(
obj => ((Person) obj).Age != 0
);
});

C# クラスの使用方法の詳細については、「POCO」を参照してください。

  • BsonClassMap

  • RegisterClassMap

  • AutoMap

戻る

直列化