0

我正在尝试进行批量插入,但它不起作用。我以为我有这个工作,但似乎有些东西坏了,如果有人能告诉我什么,我会很感激。

编辑- 这是数据库架构:

CREATE TABLE [dbo].[Categories](
    [Id] [int] IDENTITY(1,1) NOT NULL,
    [Name] [nvarchar](100) NOT NULL,
    CONSTRAINT [PK_Categories] PRIMARY KEY CLUSTERED ([Id])
)

CREATE TABLE [dbo].[ProductTopSellersCategory](
    [ProductId] [int] NOT NULL,
    [CategoryId] [int] NOT NULL,
    [Order] [int] NOT NULL,
    CONSTRAINT [PK_ProductTopSellersCategory]
          PRIMARY KEY CLUSTERED ([ProductId], [CategoryId])
)

ALTER TABLE [dbo].[ProductTopSellersCategory] ADD
    CONSTRAINT [FK_ProductTopSellersCategory_Products]
        FOREIGN KEY ([ProductId]) REFERENCES [dbo].[Products] ([Id]),
    CONSTRAINT [FK_ProductTopSellersCategory_Categories]
        FOREIGN KEY ([CategoryId]) REFERENCES [dbo].[Categories] ([Id])

我有以下实体:

public class Category {
    public virtual int Id { get; set; }
    public virtual string Name { get; set; }
}

public class ProductTopSellerCategory {
    public virtual ProductTopSellerCategoryIdentifier Id { get; set; }

    private Product _product;
    public virtual Product Product {
        get { return _product; }
        set { _product = value; Id.ProductId = _product.Id; }
    }

    private Category _category;
    public virtual Category Category {
        get { return _category; }
        set { _category = value; Id.CategoryId = _category.Id; }
    }

    [Required]
    public virtual int Order { get; set; }

    public ProductTopSellerCategory() {
        Id = new ProductTopSellerCategoryIdentifier();
    }
}

[Serializable]
public class ProductTopSellerCategoryIdentifier {
    public virtual int ProductId { get; set; }
    public virtual int CategoryId { get; set; }

    #region Composite Id Members

    public override bool Equals(object obj) {
        if (obj == null || !(obj is ProductTopSellerCategoryIdentifier))
            return false;

        var i = (ProductTopSellerCategoryIdentifier)obj;

        return ProductId == i.ProductId && CategoryId == i.CategoryId;
    }

    public override int GetHashCode() {
        return ToString().GetHashCode();
    }

    public override string ToString() {
        return ProductId + "|" + CategoryId;
    }

    #endregion
}

使用相应的流畅映射:

public class CategoryMap : ClassMap<Category> {
    public CategoryMap() {
        Table("Categories");
        Id(x => x.Id);
        Map(x => x.Name);
    }
}

public class ProductTopSellerCategoryMap : ClassMap<ProductTopSellerCategory> {
    public ProductTopSellerCategoryMap() {
        Table("ProductTopSellersCategory");
        CompositeId(x => x.Id)
            .KeyProperty(x => x.ProductId)
            .KeyProperty(x => x.CategoryId);
        References(x => x.Product).ReadOnly();
        References(x => x.Category).ReadOnly();
        Map(x => x.Order, "[Order]");
    }
}

现在当我说:

var category = new Category() { Name = "Test 1" };
var product = session.Get<Product>(1);
var topSeller = new ProductTopSellerCategory() { Product = product, Category = category };

session.SaveOrUpdate(category);

session.SaveOrUpdate(topSeller);

session.Transaction.Commit();

它抛出错误:

INSERT 语句与 FOREIGN KEY 约束“FK_ProductTopSellersCategory_Categories”冲突。数据库“xxx”、表“dbo.Categories”、“Id”列中发生冲突。该语句已终止。

我试图尽可能地简化这个例子。我真的很感激帮助。谢谢

4

2 回答 2

0

我想我找到了解决办法。这有点小技巧,但这意味着我不必更改我的实体和映射。出现此问题的原因是身份类型中的 CategoryId 未指向与畅销实体中的 Category.Id 相同的引用。要解决此问题,我需要在插入畅销商品之前添加以下内容:

topSeller.Id.CategoryId = topSeller.Category.Id;
于 2013-07-22T09:50:11.913 回答
0

您在 Category 和 ProductTopSellerCategory 之间存在一对多关系,并且仅映射了多面。通常,您会在一侧映射的集合上使用 inverse 属性,但您没有映射,所以我建议:

using (var txn = session.BeginTransaction())
{
   var category = new Category() { Name = "Test 1" };
   session.Save(category);
   session.Flush();

   var product = session.Get<Product>(1);
   var productTopSellerCategory = new ProductTopSellerCategory() { Product = product, Category = category };
   session.Save(productTopSellerCategory);
   txn.Commit();
}

您的原始代码的问题是 NHibernate 试图插入新的 ProductTopSellerCategory 然后更新类别。这样做是因为未设置 inverse 属性。通过刷新会话强制 NHibernate 插入新类别应该可以解决问题。

于 2013-07-20T13:30:36.077 回答