简体   繁体   English

(流利)带有CompositeId的NHibernate映射

[英](Fluent) NHibernate mapping with CompositeId

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. 我有一个正在运行的数据库,其中包含许多产品数据,并且我正在尝试为以下结构获取(Fluent)NHibernate映射。

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]) 但是运行代码将导致错误: 外键(FK1F94D86A1A0EC427:Product [ProductDet1_id]))必须具有与引用的主键相同的列数(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 每个产品只能有一个ProductDet1,ProductDet2 ...等

MSSQL Product Table: 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 and ProductDet2 Table: 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# product class: 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# product Det1 and product Det2 class: 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();
    }
}

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: 产品Det 1和Det 2地图:

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

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

a slightly different class structure and mapping which hide the complexity of the det class. 略有不同的类结构和映射隐藏了det类的复杂性。 It essentially sets the columns used on the References() 它本质上设置了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