如何使用 Fluent NHibernate 映射 CompositeId 的引用
How to map a reference of a CompositeId using Fluent NHibernate
我有三个 classes Product
、Stock
、StockId
。 Stock
有一个Token
和InternalCode
的复合Id,这两个属性封装在一个新的classStockID
中。
我的 classes 定义是:
public class Producto
{
public virtual long Id { get; set;
public virtual Stock Stock { get; set; }
... Some other (not so important ) properties ...
public Producto()
{
...
}
}
public class Stock
{
public virtual StockID ID { get; set; }
public virtual Producto ProductoStock { get; set; }
... other properties ...
}
public class StockID
{
public virtual string Token { get; set; }
public virtual long CodigoInterno { get; set; }
public override int GetHashCode()
{
int hash = GetType().GetHashCode();
hash = (hash * 31) ^ CodigoInterno.GetHashCode();
hash = (hash * 31) ^ Token.GetHashCode();
return hash;
}
public override bool Equals(object obj)
{
var other = obj as StockID;
if (ReferenceEquals(null, other)) return false;
if (ReferenceEquals(this, other)) return true;
return this.CodigoInterno == other.CodigoInterno &&
this.Token == other.Token;
}
}
这些是地图:
public class ProductoMap : ClassMap<Producto>
{
public ProductoMap()
{
Id(x => x.Id);
// ... Other Maps and References
References<Stock>( p => p.Stock);
}
}
public class StockMap : ClassMap<Stock>
{
public StockMap()
{
CompositeId( stock => stock.ID)
.KeyProperty(x => x.CodigoInterno)
.KeyProperty(x => x.Token);
// ... Other Maps and References
References(x => x.ProductoStock);
}
}
这是我得到的异常...
Foreign key (FKD33BD86ADE26BE17:Producto [Stock_id])) must have same number of columns as the referenced primary key (Stock [CodigoInterno, Token])
我该如何解决这个问题?
您必须将与您的 class Producto 匹配的 属性 映射到您的 class 库存。它应该是这样的:
public class StockMap : ClassMap<Stock>
{
public StockMap()
{
CompositeId( stock => stock.ID)
.KeyProperty(x => x.CodigoInterno)
.KeyProperty(x => x.Token);
// ... Other Maps and References
//This is ok since you have (i believe) a column in
//in your table that stores the id from Producto
References(x => x.ProductoStock).Column("idProducto");
//Maybe you have to put the name of the column with
//the id of Producto in your table Stock because
//you could use it later.
}
}
和 ProductMap class:
public class ProductoMap : ClassMap<Producto>
{
public ProductoMap()
{
Id(x => x.Id);
// ... Other Maps and References
//If you have the id from Stock in your Stock class
//this will work.
//References<Stock>( p => p.Stock);
//If you don't have it, this will work:
HasOne<Stock>(x => x.Stock).PropertyRef("Name of the column whit the product id in the Stock table");
}
}
从我的角度来看,第二个选择似乎更好。不管怎样,如果你有一个遗留数据库 o 类似的东西并没有太大的区别。
我有三个 classes Product
、Stock
、StockId
。 Stock
有一个Token
和InternalCode
的复合Id,这两个属性封装在一个新的classStockID
中。
我的 classes 定义是:
public class Producto
{
public virtual long Id { get; set;
public virtual Stock Stock { get; set; }
... Some other (not so important ) properties ...
public Producto()
{
...
}
}
public class Stock
{
public virtual StockID ID { get; set; }
public virtual Producto ProductoStock { get; set; }
... other properties ...
}
public class StockID
{
public virtual string Token { get; set; }
public virtual long CodigoInterno { get; set; }
public override int GetHashCode()
{
int hash = GetType().GetHashCode();
hash = (hash * 31) ^ CodigoInterno.GetHashCode();
hash = (hash * 31) ^ Token.GetHashCode();
return hash;
}
public override bool Equals(object obj)
{
var other = obj as StockID;
if (ReferenceEquals(null, other)) return false;
if (ReferenceEquals(this, other)) return true;
return this.CodigoInterno == other.CodigoInterno &&
this.Token == other.Token;
}
}
这些是地图:
public class ProductoMap : ClassMap<Producto>
{
public ProductoMap()
{
Id(x => x.Id);
// ... Other Maps and References
References<Stock>( p => p.Stock);
}
}
public class StockMap : ClassMap<Stock>
{
public StockMap()
{
CompositeId( stock => stock.ID)
.KeyProperty(x => x.CodigoInterno)
.KeyProperty(x => x.Token);
// ... Other Maps and References
References(x => x.ProductoStock);
}
}
这是我得到的异常...
Foreign key (FKD33BD86ADE26BE17:Producto [Stock_id])) must have same number of columns as the referenced primary key (Stock [CodigoInterno, Token])
我该如何解决这个问题?
您必须将与您的 class Producto 匹配的 属性 映射到您的 class 库存。它应该是这样的:
public class StockMap : ClassMap<Stock>
{
public StockMap()
{
CompositeId( stock => stock.ID)
.KeyProperty(x => x.CodigoInterno)
.KeyProperty(x => x.Token);
// ... Other Maps and References
//This is ok since you have (i believe) a column in
//in your table that stores the id from Producto
References(x => x.ProductoStock).Column("idProducto");
//Maybe you have to put the name of the column with
//the id of Producto in your table Stock because
//you could use it later.
}
}
和 ProductMap class:
public class ProductoMap : ClassMap<Producto>
{
public ProductoMap()
{
Id(x => x.Id);
// ... Other Maps and References
//If you have the id from Stock in your Stock class
//this will work.
//References<Stock>( p => p.Stock);
//If you don't have it, this will work:
HasOne<Stock>(x => x.Stock).PropertyRef("Name of the column whit the product id in the Stock table");
}
}
从我的角度来看,第二个选择似乎更好。不管怎样,如果你有一个遗留数据库 o 类似的东西并没有太大的区别。