0

我已经开始在 C# 中测试 Fluent NHibernate 我有一个规范化的对象结构,其中包含 20 个相关类。我目前使用 Fluent 1.3 和 NHibernate 3.2。到目前为止,我已经设法使用了适合我的 AutoMap 功能,非常方便!

但是...其中 3 个表是“枚举表”,需要将其记录设置为特定的 Id 值。我试图对这些表进行手动映射,并让其余的自动映射。但是当创建手动表时它会失败,因为它引用了一个自动映射的表(并且不适用于手动映射器?)

是否可以使用 AutoMapping 但对于一些极少数的类会覆盖主键上的标识创建?我试图制定一个自定义约定,但没有成功。

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 回答