I have a running database with a lot of prodcut data and I'm trying to get a (Fluent) NHibernate mapping for the structure below.
But running the code will result in an error: Foreign key (FK1F94D86A1A0EC427:Product [ProductDet1_id])) must have same number of columns as the referenced primary key (ProductDet1 [ProductNumber, ProductionLine])
So something went wrong during mapping but can't figure out what it is. Is there somebody who can get me out of this problem? :-)
(Ofcource I let out all specific details in the tables, just to make it readable)
We hava a product table where the productnumber in combination with production line is unique. Every Product can have only one ProductDet1, ProductDet2 ... etc
MSSQL Product Table:
CREATE TABLE [dbo].[Product] (
[Id] INT NOT NULL IDENTITY,
[ProductNumber] INT NOT NULL,
[ProductionLine] INT NOT NULL,
CONSTRAINT [AK_Product_ProductNumber] UNIQUE ([ProductNumber], [ProductionLine]),
CONSTRAINT [PK_Product] PRIMARY KEY ([Id])
);
MSSQL ProductDet1 and ProductDet2 Table:
CREATE TABLE [dbo].[ProductDet1] (
[ProductNumber] INT NOT NULL,
[ProductionLine] INT NOT NULL,
[TheValue] VARCHAR (15) NULL,
CONSTRAINT [FK_ProductDet1_Product] FOREIGN KEY ([ProductNumber], [ProductionLine]) REFERENCES [Product]([ProductNumber],[ProductionLine]),
CONSTRAINT [AK_ProductDet1_ProductNumber] UNIQUE ([ProductNumber], [ProductionLine])
);
GO
CREATE INDEX [IX_ProductDet1_ProductNumber] ON [dbo].[ProductDet1] ([ProductNumber])
GO
CREATE INDEX [IX_ProductDet1_ProductionLine] ON [dbo].[ProductDet1] ([ProductionLine])
C# product class:
public class Product
{
public Product ()
{
ProductDet1 = new ProductDet1();
ProductDet2 = new ProductDet2();
}
public virtual int Id { get; set; }
public virtual int ProductionLine { get; set; }
public virtual int ProductNumber { get; set; }
public virtual string ProductName { get; set; }
public virtual ProductDet1 ProductDet1 { get; set; }
public virtual ProductDet2 ProductDet2 { get; set; }
public override bool Equals(object obj)
{
// If parameter is null return false.
if (obj == null)
{
return false;
}
// If parameter cannot be cast to Reference return false.
var product = obj as Product;
if (product == null)
{
return false;
}
// Return true if the fields match:
return this.ProductionLine == product.ProductionLine && this.ProductNumber == product.ProductNumber;
}
public override int GetHashCode()
{
return base.GetHashCode();
}
}
C# product Det1 and product Det2 class:
public class ProductDet1
{
public virtual int Id { get; set; }
public virtual int ProductionLine { get; set; }
public virtual int ProductNumber { get; set; }
public virtual string TheValue { get; set; }
public virtual Product Product { get; set; }
public override bool Equals(object obj)
{
// If parameter is null return false.
if (obj == null)
{
return false;
}
// If parameter cannot be cast to Reference return false.
var product = obj as ProductCRT;
if (product == null)
{
return false;
}
// Return true if the fields match:
return this.ProductionLine == product.ProductionLine && this.ProductNumber == product.ProductNumber;
}
public override int GetHashCode()
{
return base.GetHashCode();
}
}
Product Map:
public class ProductEntityMap : ClassMap<Product>
{
public ProductEntityMap()
{
Id(x => x.Id);
Map(x => x.ProductNumber);
Map(x => x.ProductionLine);
Map(x => x.ProductName);
References(x => x.ProductDet1).Cascade.All().Not.LazyLoad();
References(x => x.ProductDet2).Cascade.All().Not.LazyLoad();
}
}
Product Det 1 and Det 2 Map:
public class ProductDet1EntityMap : ClassMap<ProductDet1>
{
public ProductDet1EntityMap()
{
CompositeId().KeyProperty(x => x.ProductNumber).KeyProperty(x => x.ProductionLine);
Map(x => x.TheValue);
}
}