簡體   English   中英

(流利)帶有CompositeId的NHibernate映射

[英](Fluent) NHibernate mapping with CompositeId

我有一個正在運行的數據庫,其中包含許多產品數據,並且我正在嘗試為以下結構獲取(Fluent)NHibernate映射。

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

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

(當然,我在表中列出了所有特定的細節,只是為了使其易於閱讀)

我們有一個產品表,其中產品編號與生產線組合是唯一的。 每個產品只能有一個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();
    }
}

產品Det 1和Det 2地圖:

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

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

略有不同的類結構和映射隱藏了det類的復雜性。 它本質上設置了References()上使用的列

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM