C# 如何映射主键和标识符不在同一列的表?

C# 如何映射主键和标识符不在同一列的表?,c#,nhibernate,mapping,fluent,C#,Nhibernate,Mapping,Fluent,我必须访问一个遗留数据库,其中我面临以下问题: 列“unit_name”被定义为主键,是字符串,另一列“id”被定义为经典int标识符 我的问题是-我如何在Fluent NHibernate中正确映射这一点 目前我的映射看起来是这样的,但我找不到任何适合我的场景的文档,所以我不确定它是否正确 public InputMap() { Table("input"); Map(x => x.unit_name).Not.Nullable().Uni

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

在寻找文档的过程中,我创建了一个id类,它实现了Equals和GetHashCode,但这毕竟可能有些过分

[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);
    }
}
创建抽象基的原因是,我希望有一个通用基,可以用于我的所有存储库,无论它们是字符串主键还是复合键(或者标识符)

[可序列化]
公共抽象类EntityBase
{
公共抽象EntityId EntityId{get;}
受保护的EntityBase()
{
}
}
公共类GenericRepository:SessionManagerBase,EntityRepository其中tenty:EntityBase
{
公共TEntity GetById(EntityId)
{
ISession currentSession=OpenSession;
var returnObject=currentSession.Get(id);
返回对象;
}
}

这是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);
        });
    }
}
公共类TestEntityMap:ClassMapping
{
公共测试地图()
{
Id(x=>x.unit\u名称,map=>
{
地图栏(“用户名”);
地图生成器(生成器已分配);
});
属性(x=>x.id,map=>
{
map.Generated(PropertyGeneration.Always);
地图。唯一(真实);
map.NotNullable(true);
});
}
}

你能解释一下为什么用户名列应该映射为id而不是id列,id列是标识符吗?因为,正如你所说,这是表的主键。为什么要创建一个表,在一列中有主键,然后使用另一列作为标识符?好处是什么?根据您的回答,我假设NHibernate Id=key而不是identifier?@Thestrup是的,NHibernate映射中的“Id()”是告诉NH使用什么作为主键。另一列名为“id”这一事实并不重要,MS SQL中的“identifier”列属性主要是MS SQL特有的—它在关系数据库理论中没有对应项,基本上是一个MS SQL实现细节,可以用作主键。
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);
        });
    }
}