我已经开始在C#中测试Fluent NHibernate,我有一个很好的规范化的对象结构,有20个相关的类。我目前使用的是Fluent1.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();
}
}还有别的办法吗?如果被迫对所有类都使用手动映射,那将是可悲的……
发布于 2012-02-07 20:25:55
我使用了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-06 20:44:17
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);https://stackoverflow.com/questions/9120135
复制相似问题