1

我有一個正在運行的數據庫與很多產品數據,我試圖得到(流利)NHibernate映射下面的結構。(流利)與CompositeId NHibernate映射

但運行代碼將導致錯誤: 外鍵(FK1F94D86A1A0EC427:產品[ProductDet1_id]))必須有相同數量的被引用的主鍵列(ProductDet1 [ProductNumber,ProductionLine])

因此,在映射過程中出現了問題,但無法弄清楚它是什麼。有沒有人能讓我擺脫這個問題? :-)

(Ofcource我讓出了表中的所有具體細節,只是爲了可讀性)

我們哈瓦產品表,其中在組合productnumber生產線是獨一無二的。每個產品只能有一個ProductDet1,ProductDet2 ...等

MSSQL產品表:

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和ProductDet2表:

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#產品類別:

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#產品Det1和產品Det2類:

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

產品地圖:

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

產品挪威1和2挪威地圖:

public class ProductDet1EntityMap : ClassMap<ProductDet1> 
{ 
    public ProductDet1EntityMap() 
    { 
     CompositeId().KeyProperty(x => x.ProductNumber).KeyProperty(x => x.ProductionLine); 

     Map(x => x.TheValue); 
    } 
} 

回答

1

略微不同的類結構和映射,其隱藏所述DET類的複雜性。它基本上設置了參考文獻中使用的列()

public class Product 
{ 
    private ProductDet ProductDet1 { get; set; } 
    private ProductDet ProductDet2 { get; set; } 

    protected Product() { } // make NHibernate happy 

    public Product(int productionLine, int productNumber) : this(new ProductKey(productionLine, productNumber)) { } 
    public Product(ProductKey key) 
    { 
     Key = key; 
     ProductDet1 = new ProductDet { ProductKey = Key }; 
     ProductDet2 = new ProductDet { ProductKey = Key }; 
    } 

    public virtual int ID { get; protected set; } 
    public virtual ProductKey Key { get; protected set; } 

    public virtual string Det1 
    { 
     get { return ProductDet1.Value; } 
     set { ProductDet1.Value = value; } 
    } 
    public virtual string Det2 
    { 
     get { return ProductDet2.Value; } 
     set { ProductDet2.Value = value; } 
    } 
} 

public class ProductKey 
{ 
    protected ProductKey() { } // make NHibernate happy 

    public ProductKey(int productionLine, int productNumber) 
    { 
     ProductionLine = productionLine; 
     ProductNumber = productNumber; 
    } 
    public virtual int ProductionLine { get; private set; } 
    public virtual int ProductNumber { get; private set; } 

    public override bool Equals(object obj) 
    { 
     var other = obj as ProductKey; 
     return other != null && other.ProductionLine == this.ProductionLine && other.ProductNumber == this.ProductNumber; 
    } 

    public override int GetHashCode() 
    { 
     return (ProductionLine << 16) + ProductNumber; 
    } 
} 

public class ProductDet 
{ 
    public virtual ProductKey ProductKey { get; set; } 
    public virtual string Value { get; set; } 
} 

public class ProductMap : ClassMap<Product> 
{ 
    public ProductMap() 
    { 
     Id(x => x.ID); 

     Component(x => x.Key, c => 
     { 
      c.Map(k => k.ProductionLine).UniqueKey("product_key"); 
      c.Map(k => k.ProductNumber).UniqueKey("product_key"); 
     }); 

     MapProductDetReference("ProductDet1"); 
     MapProductDetReference("ProductDet2"); 
    } 

    private void MapProductDetReference(string entityName) 
    { 
     References(Reveal.Member<Product, ProductDet>(entityName)) 
      .Columns("ProductionLine", "ProductNumber") 
      .ReadOnly() 
      .EntityName(entityName) 
      .Cascade.All() 
      .Fetch.Join() 
      .Not.LazyLoad(); 
    } 
} 

public abstract class ProductDetMap : ClassMap<ProductDet> 
{ 
    public ProductDetMap() 
    { 
     CompositeId(x => x.ProductKey) 
      .KeyProperty(k => k.ProductionLine) 
      .KeyProperty(k => k.ProductNumber); 

     Map(x => x.Value, "TheValue"); 
    } 
} 

public class ProductDet1Map : ProductDetMap 
{ 
    public ProductDet1Map() 
    { 
     EntityName("ProductDet1"); 
     Table("ProductDet1"); 
    } 
} 
public class ProductDet2Map : ProductDetMap 
{ 
    public ProductDet2Map() 
    { 
     EntityName("ProductDet2"); 
     Table("ProductDet2"); 
    } 
} 
+0

太好了!那就是訣竅! – JeKr 2014-09-25 13:00:55

+0

在實時數據庫中,我不得不將「.NotFound.Ignore()」添加到ProductMap中的引用,因爲細節並不總是存在。 Tnx @Firo! – JeKr 2014-09-26 07:26:06