c# - 避免在双链场景下指定key列

标签 c# .net nhibernate fluent-nhibernate

假设我有以下两个类:

public class User : Entity
{
    public virtual IList<Item> Items { get; set; }
}

public class Item : Entity
{
    public virtual User Owner { get; set; }
}

我创建了两个映射类:

public class UserMap : ClassMap<User>
{
    public UserMap()
    {
        Id(x => x.Id);
        HasMany(x => x.Items);
    }
}

public class ItemMap : ClassMap<Item>
{
    public ItemMap()
    {
        Id(x => x.Id);
        References(x => x.Owner);
    }
}

这将生成一个表 Item,其中有一列 UserId 和一列 OwnerId。当我在 HasMany 映射上使用 KeyColumn("OwnerId") 时,它仅适用于 OwnerId 列,但我想避免这种情况.有没有办法告诉 NHibernate,使用 ItemMap 中的映射创建的列?

为什么我想避免明确指定列:
列名称 OwnerId 是根据属性名称和一些规则自动生成的。如果我更改规则或属性名称,我需要记住也更改 KeyColumn。所以,基本上,它不是重构保存。

最佳答案

更新:修复了错误

如果你在 map 中应用规则,那么

public static void KeyColumnFromReference<TChild>(
    this OneToManyPart<TChild> collectionmap, ClassMap<TChild> map, Expression<Func<TChild, object>> referenceprop)
{
    string propertyname = GetPropertyName(referenceprop);
    var column = ((IMappingProvider)map).GetClassMapping()
        .References.First(m => m.Name == propertyname)
        .Columns.First().Name;

    collectionmap.KeyColumn(column);
}

public static void KeyColumnFromReference<T, TChild>(
    this OneToManyPart<TChild> collectionmap, ClassMap<TChild> map)
{
    var column = ((IMappingProvider)map).GetClassMapping()
        .References.First(m => m.Type == typeof(TChild))
        .Columns.First().Name;

    collectionmap.KeyColumn(column);
}

public UserMap()
{
    HasMany(x => x.Items)
        .KeyColumnFromReference<User, Item>(new ItemMap());

    // or

    HasMany(x => x.Items)
        .KeyColumnFromReference(new ItemMap(), u => u.Owner);
}

如果您将规则作为约定应用,那么您需要实现 IHasManyConvention 并对 EntityType 和属性名称应用相同的规则(您必须通过反射获得子类型)

更新:

class ForeignKeyConvention : IHasManyConvention
{
    public void Apply(IOneToManyCollectionInstance instance)
    {
        // to force the compiler to take the Name property and not the Name method
        string propertyName = ((ICollectionInspector)instance).Name;

        // should be equal to the convention for the reference key column
        instance.Key.Column(propertyName + instance.EntityType.Name + "id");
    }
}

关于c# - 避免在双链场景下指定key列,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8022608/

相关文章:

C# Mongo 驱动程序 - MongoCollection.Group 方法

c# - 无法弄清楚异常消息

c# - NHibernate (Hibernate) 属性自动递增

nhibernate - SchemaUpdate 不会删除表或删除列

c# - 为什么从 C# 应用程序代码调用 Powershell 时返回 null?

c# - 无法使用 C# 和 SSH.NET 从 Windows 运行 Unix 服务器中的用户脚本

c# - 公共(public)类和方法会降低您的代码速度吗?

.net - Moq - 设置属性以从方法参数返回字符串

C# Nhibernate 映射到查找表

c# - 在 C# 中的字符串中添加换行符