如何映射表主键和标识符不是同一列?

时间:2014-08-06 12:47:50

标签: c# nhibernate mapping fluent

我必须访问我面临以下问题的遗留数据库: 列'unit_name'被定义为主键并且是一个字符串,另一列'id'被定义为经典的int标识符。

我的问题是 - 如何在Fluent NHibernate中正确映射这个?

目前我的映射看起来像这样,但我找不到适合我的方案的文档,所以我不确定它是否正确。

    public InputMap()
    {
        Table("input");
        Map(x => x.unit_name).Not.Nullable().Unique();
        //other mappings ...
        Id(x => x.id).Column("id").Not.Nullable();
        //Maybe use this instead? NaturalId().Property(x => x.unit_name);            
    }

完整背景:

在我搜索文档的过程中,我创建了一个实现Equals和GetHashCode的id类,但毕竟这可能是一种过度杀伤。

[Serializable]
public class GenericEntityId : EntityId, IEquatable<GenericEntityId>
{
    public GenericEntityId(string idString)
    {
        IdString = idString;
    }

    public string IdString { get; set; }

    private Guid _internalId { get; set; }

    protected GenericInoEntityId()
    {
        _internalId = Guid.NewGuid();
    }

    public virtual bool Equals(GenericEntityId obj)
    {
        if (ReferenceEquals(null, obj)) return false;
        if (ReferenceEquals(this, obj)) return true;
        if (GetType() != obj.GetType()) return false;
        if (!string.IsNullOrEmpty(IdString) )
            return obj.IdString == IdString;
        return false;
    }

    public override bool Equals(object obj)
    {
        if (ReferenceEquals(null, obj)) return false;
        if (ReferenceEquals(this, obj)) return true;
        if (GetType() != obj.GetType()) return false;
        return Equals((GenericEntityId)obj);
    }

    public override int GetHashCode()
    {
        if (!string.IsNullOrEmpty(IdString))
        {
            return (IdString.GetHashCode() * 397) ^ GetType().GetHashCode();
        }
        else
        {
            return (_internalId.GetHashCode() * 397) ^ GetType().GetHashCode();
        }
    }

    public static bool operator ==(GenericEntityId left, GenericEntityId right)
    {
        return Equals(left, right);
    }

    public static bool operator !=(GenericEntityId left, GenericEntityId right)
    {
        return !Equals(left, right);
    }
}

和EntityId只是一个抽象类:

public abstract class EntityId
{
    public abstract override int GetHashCode();
}

创建抽象基础的原因是我希望拥有一个可以用于所有存储库的通用基础,无论它们是否具有字符串主键或复合键(或者可能是标识符)

[Serializable]
public abstract class EntityBase
{
    public abstract EntityId entityId { get; }

    protected EntityBase()
    {
    }
}

public class GenericRepository<TEntity> : SessionManagerBase, IEntityRepository<TEntity> where TEntity : EntityBase
{
    public TEntity GetById(EntityId id)
    {
        ISession currentSession = OpenSession;

        var returnObject = currentSession.Get<TEntity>(id);
        return returnObject;
    }
}

1 个答案:

答案 0 :(得分:0)

这是Nhibernate按代码映射,但是流利的应该是类似的

域对象类

public class TestEntity
{
    public String unit_name { get; set; }
    public Int32 id { get; protected set; }
}

映射类

public class TestEntityMap : ClassMapping<TestEntity>
{
    public TestEntityMap()
    {
        Id( x => x.unit_name, map =>
        {
            map.Column("user_name");
            map.Generator(Generators.Assigned);
        });

        Property(x => x.id, map =>
        {
            map.Generated(PropertyGeneration.Always);
            map.Unique(true);
            map.NotNullable(true);
        });
    }
}