LINQ-to-LDAP モデルを構築するために、いくつかの異なるツールを使用してきました。ほぼ完成しましたが、返されたデータをクラスにバインドしようとしていくつかの問題が発生しています。
データベース フィールドの実際の名前であるクラスのプロパティにカスタム属性を割り当てることで、逆の部分を行います。
クラスとカスタム属性の例を次に示します (DirectorySchemaAttribute
とのDirectoryRootAttribute
実装は含まれていません... これらの部分は正しく機能しています)。
[DirectorySchema("C4User"), DirectoryRoot("o=c4, ou=users")]
class User
{
[DirectoryAttribute("cn")]
public string Username { get; set; }
[DirectoryAttribute("userpassword")]
public string Password { get; set; }
[DirectoryAttribute("C4-Parent")]
public string Parent { get; set; }
}
/// <summary>
/// Specifies the underlying attribute to query for in the directory.
/// </summary>
[AttributeUsage(AttributeTargets.Property, AllowMultiple = false)]
public class DirectoryAttributeAttribute : Attribute
{
private string attribute;
private DirectoryAttributeType type;
/// <summary>
/// Creates a new attribute binding attribute for a entity class field or property.
/// </summary>
/// <param name="attribute">Name of the attribute to query for.</param>
public DirectoryAttributeAttribute(string attribute)
{
this.attribute = attribute;
this.type = DirectoryAttributeType.Ldap;
}
/// <summary>
/// Creates a new attribute binding attribute for a entity class field or property.
/// </summary>
/// <param name="attribute">Name of the attribute to query for.</param>
/// <param name="type">Type of the underlying query source to get the attribute from.</param>
public DirectoryAttributeAttribute(string attribute, DirectoryAttributeType type)
{
this.attribute = attribute;
this.type = type;
}
/// <summary>
/// Name of the attribute to query for.
/// </summary>
public string Attribute
{
get { return attribute; }
set { attribute = value; }
}
/// <summary>
/// Type of the underlying query source to get the attribute from.
/// </summary>
public DirectoryAttributeType Type
{
get { return type; }
set { type = value; }
}
}
そのため、LDAP 検索の属性にプロパティの DirectoryAttributeAttribute::Name 値を設定しています。指定されていない場合は、Property の Type 名を使用します。したがって、本質的に、User.Username は「cn」などにマップされます。
逆にどうするのが一番いいのか悩んでいます。したがって、「cn」という名前のフィールドを含む LDAP 結果が返された場合、「cn」に等しい DirectoryAttributeAttribute.Name を持つプロパティを見つけるにはどうすればよいでしょうか。私は各プロパティのカスタム属性を取得する foreach に取り組んでいますが、結果セットのすべてのフィールドに対してその foreach を実行する必要があります :( ちょっと面倒です。これを行うためのより良い方法を考えられる人はいますか?
プロパティがマップされるフィールド名を決定する関数のコードを次に示します。
private string GetFieldName(System.Reflection.MemberInfo member)
{
DirectoryAttributeAttribute[] da = member.GetCustomAttributes(typeof(DirectoryAttributeAttribute), false) as DirectoryAttributeAttribute[];
if (da != null && da.Length != 0)
{
if (da[0].Type == DirectoryAttributeType.ActiveDs)
throw new InvalidOperationException("Can't execute query filters for IADs* properties.");
else
return da[0].Attribute;
}
else
return member.Name;
}
ありがとう、クリス