クラスマッピング
項目一覧
Overview
このガイドでは、MongoDB .NET/C# ドライバーで BSON ドキュメントと C# クラス間のマッピングをカスタマイズする方法を学習できます。デフォルトのクラスマッピング動作の詳細を確認したり、ドライバーでデータを直列化または逆直列化化する方法をカスタマイズしたりする必要がある場合にお読みください。
自動クラスマッピング
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"); });
クラス直列化をカスタマイズする
クラスの属性を使用するか、クラス マップの登録時にメソッドを呼び出すことで、ドライバーがクラス レベルでドキュメントを直列化および逆直列化化する方法をカスタマイズできます。
余計な要素を無視する
BSON ドキュメントが C# クラスに逆直列化されると、.NET/C# ドライバーはドキュメント内の各フィールドの名前を調べ、クラス内の一致するプロパティ名を見つけようとします。デフォルトでは、ドキュメント内のフィールドがクラス内で一致しない場合、ドライバーは例外をスローします。
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); });
コンストラクタによるマッピング
デフォルトでは、.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;} [ ] 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;} [ ] 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」を参照してください。