C# 如何映射主键和标识符不在同一列的表?
我必须访问一个遗留数据库,其中我面临以下问题: 列“unit_name”被定义为主键,是字符串,另一列“id”被定义为经典int标识符 我的问题是-我如何在Fluent NHibernate中正确映射这一点 目前我的映射看起来是这样的,但我找不到任何适合我的场景的文档,所以我不确定它是否正确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
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);
});
}
}