【问题标题】:How do I map a table were primary key and identifier is not the same column?如何映射一个表被主键和标识符不是同一列?
【发布时间】:2014-09-29 09:58:27
【问题描述】:

我必须访问一个遗留数据库,其中我面临以下问题: 一列'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;
    }
}

【问题讨论】:

    标签: c# nhibernate mapping fluent


    【解决方案1】:

    这是 Nhibernate 代码映射,但 fluent 应该类似

    领域对象类

    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);
            });
        }
    }
    

    【讨论】:

    • 你能解释一下为什么 user_name 列应该映射为 id 而不是 id 列,即标识符?
    • 因为,正如您所说,这是表的主键。
    • 为什么要在一个列中创建一个主键的表,然后使用另一列作为标识符?有什么好处?根据您的回答,我假设 NHibernate Id = 键而不是标识符?
    • @Thestrup 是的,NHibernate 映射中的“Id()”是告诉 NH 使用什么作为主键。另一列名为“id”的事实并不重要,MS SQL 中的“标识符”列属性主要是 MS SQL 特有的——它在关系数据库理论中没有对应物,基本上是 MS SQL 实现细节可以用作主键。
    猜你喜欢
    • 2011-08-10
    • 2011-12-04
    • 2023-02-22
    • 1970-01-01
    • 2021-07-03
    • 1970-01-01
    • 1970-01-01
    • 2014-04-16
    • 1970-01-01
    相关资源
    最近更新 更多