Docs Menu
Docs Home
/ / /
C#/.NET
/ /

クラスマッピング

項目一覧

  • Overview
  • 自動クラスマッピング
  • クラスマップの手動作成
  • クラス直列化をカスタマイズする
  • 余計な要素を無視する
  • コンストラクタによるマッピング
  • プロパティ直列化をカスタマイズする
  • 追加要素をサポートする
  • プロパティを動的に直列化する
  • 詳細情報
  • API ドキュメント

このガイドでは、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 属性を追加する方法を示しています。

[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;}
[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」を参照してください。

戻る

直列化