0

私は C# で Fluent NHibernate のテストを開始しました。20 の関連クラスを持つ適切に正規化されたオブジェクト構造があります。現在、NHibernate 3.2 で Fluent 1.3 を使用しています。これまでのところ、私は自分に合った AutoMap 機能を使用することができました。非常に便利です!

しかし... 3つのテーブルは「列挙テーブル」であり、特定のID値でレコードを設定する必要があります。これらのテーブルを手動でマッピングして、残りを自動マッピングしようとしました。しかし、手動テーブルが作成されると、自動マップされたテーブルを参照するため失敗します (手動マッパーでは使用できませんか?)。

AutoMapping を使用することは可能ですが、一部のクラスでは主キーで ID の作成をオーバーライドしますか? カスタム規約を作成しようとしましたが、成功しませんでした。

public class OverrideIdentityGeneration : Attribute
{
}

public class ConventionIdentity : AttributePropertyConvention<OverrideIdentityGeneration>
{
    protected override void Apply(OverrideIdentityGeneration attribute, IPropertyInstance instance)
    {
        instance.Generated.Never();
    }
}

他の方法はありますか?すべてのクラスで手動マッピングを使用することを余儀なくされるのは悲しいことです....

4

2 に答える 2

4
class MyIdConvention : IIdConvention
{
    public void Apply(IIdentityInstance instance)
    {
        if (instance.EntityType == ...)
        {
            instance.GeneratedBy.Assigned();
        }
    }
}

アップデート:

列挙型のクラスの場合、列挙型を id として定義する方が簡単なことがよくあります

class ConfigValue
{
    public virtual Config Id { get; set; }
}

// the convention is easy
if (instance.EntityType.IsEnum)
{
    instance.GeneratedBy.Assigned();
    // to save as int and not string
    instance.CustomType(typeof(Config));
}

// querying without magic int values
var configValue = Session.Get<ConfigValue>(Config.UIColor);
于 2012-02-06T12:44:16.603 に答える
-2

Fifo から提供されたアイデアを使用し、代わりにカスタム属性を使用するように拡張しました。コードを読みやすくし、他の規則で同様のアイデアを使用するときに冗長性を避けるために、カスタム属性をチェックする拡張メソッドを追加しました。

これは私が最終的に得たコードです:

/// <summary>
/// Convention to instruct FluentNHIbernate to NOT generate identity columns
/// when custom attribute is set.
/// </summary>
public class ConventionIdentity : IIdConvention
{
    public void Apply(IIdentityInstance instance)
    {
        if(instance.CustomAttributeIsSet<NoIdentity>())
            instance.GeneratedBy.Assigned();
    }
}

/// <summary>
/// Custom attribute definition.
/// </summary>
public class NoIdentity : Attribute
{
}

/// <summary>
/// Example on how to set attribute.
/// </summary>
public class Category
{
    [NoIdentity]
    public int Id { get; set; }
    public string Name { get; set; }
}

public static class IInspectorExtender
{
    /// <summary>
    /// Extender to make convention usage easier.
    /// </summary> 
    public static T GetCustomAttribute<T>(this IInspector instance)
    {
        var memberInfos = instance.EntityType.GetMember(instance.StringIdentifierForModel);
        if(memberInfos.Length > 0)
        {
            var customAttributes = memberInfos[0].GetCustomAttributes(false);
            return customAttributes.OfType<T>().FirstOrDefault();
        }
        return default(T);
    }
}
于 2012-02-07T12:25:54.653 に答える