Nhibernate пытается добавить дубликат столбца при сохранении - PullRequest
1 голос
/ 06 октября 2011

Я пытаюсь использовать Fluent NHibernate. У меня есть две таблицы продуктов и категорий. В продуктах есть поле CategoryID и внешний ключ, который связывает CategoryID продуктов с PK (CategoryID) таблицы Categories.

DTO: Класс продукта:

public class Product
{
    [HiddenInput(DisplayValue = false)]
    public virtual int ProductId { get; set; }
    public virtual string Name { get; set; }
    public virtual int CategoryId { get; set; }

    [DataType(DataType.MultilineText)]
    public virtual string Description { get; set; }
    public virtual decimal Price { get; set; }
    public virtual decimal SalePrice { get; set; }
    public virtual int StockAmt { get; set; }
    public virtual bool StockLevelWarning { get; set; }
    public virtual string Dimensions { get; set; }
    public virtual bool PriceIncludesTax { get; set; }
    public virtual string TaxClass { get; set; }
    public virtual decimal ProductWeight { get; set; }
    public virtual decimal CubicWeight { get; set; }
    public virtual string PackageDimensions { get; set; }
    public virtual bool IncludeLatestProduct { get; set; }
    public virtual Category Category { get; set; }

    public Product()
    {
        Name = String.Empty;
        Description = String.Empty;
        Price = 0m;
        SalePrice = 0m;
        StockAmt = 0;
        StockLevelWarning = true;
        Dimensions = String.Empty;
        PriceIncludesTax = false;
        TaxClass = String.Empty;
        ProductWeight = 0;
        CubicWeight = 0;
        PackageDimensions = String.Empty;
        IncludeLatestProduct = false;
    }
}

В моем классе ProductMap у меня есть все, что указано в Fluent Documentation, включая последнее свойство, установленное как Reference:

   public class ProductMap : ClassMap<Product>
{
    public ProductMap()
    {
        Table("Products");
        Id(x => x.ProductId);
        Map(x => x.Name);
        Map(x => x.CategoryId);
        Map(x => x.Description);
        Map(x => x.Price);
        Map(x => x.SalePrice);
        Map(x => x.StockAmt);
        Map(x => x.StockLevelWarning);
        Map(x => x.Dimensions);
        Map(x => x.PriceIncludesTax);
        Map(x => x.TaxClass);
        Map(x => x.ProductWeight);
        Map(x => x.CubicWeight);
        Map(x => x.PackageDimensions);
        Map(x => x.IncludeLatestProduct);
        References(x => x.Category);
    }
}

DTO: Категория:

public class Category
{
    public virtual int CategoryId { get; set; }
    public virtual string Name { get; set; }
    public virtual string Description { get; set; }
    public virtual IList<Product> Products { get; set; }

    public Category()
    {
        Name = string.Empty;
        Description = string.Empty;
    }
}



public class CategoryMap : ClassMap<Category>
{
    public CategoryMap()
    {
        Table("Categories");
        Id(x => x.CategoryId);
        Map(x => x.Name);
        Map(x => x.Description).Column("CategoryDescription");
        HasMany(x => x.Products);
    }
}

Однако, когда я пытаюсь сохранить объект Product, я получаю ошибку MySQL в ответ, что я пытаюсь добавить CategoryID дважды. При просмотре трассировки стека указывается, какие столбцы пытается сохранить NHibernate. И действительно, он перечисляет не только CategoryID в порядке, указанном мной в классе ProductMap, но и снова в качестве последнего столбца в операторе вставки.

  Error:
  "could not insert: [DTOS.Product][SQL: INSERT INTO Products (Name, CategoryId, Description, Price, SalePrice, StockAmt, StockLevelWarning, Dimensions, PriceIncludesTax, TaxClass, ProductWeight, CubicWeight, PackageDimensions, IncludeLatestProduct, Categoryid) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)]"}

Я следую примеру автора и книги, который использует документация Fluent.

Это похоже на то, как если бы оно приравнивало свойство (тип Category) в классе Product к первичному ключу таблицы Category. Но, как я уже говорил, я использую тот же пример из примера кода Fluent.

Ответы [ 3 ]

1 голос
/ 08 октября 2011

Над ответом является правильным.

Если вам нужен categoryId, тогда сделайте Product.Category.Id.

0 голосов
/ 07 октября 2011

хорошо, если вы внимательно посмотрите на отображение, есть две записи, которые создадут столбец categoryid в БД для вас.

Map(x => x.CategoryId);

References(x => x.Category);

Ну, вы можете удалить один из них или, если вам нужны оба, тогдаустановить имя столбца одного из тех, что явно как category_id.если это общее для всех ваших ссылок, используйте соглашение, которое вы можете указать для отношения с внешним ключом.

также если вы посмотрите на сгенерированный sql, вы увидите CategoryId и Cateogryid вторую.будучи эталоном.

0 голосов
/ 07 октября 2011

Я бы попытался указать имена столбцов в вашем отображении:

public class ProductMap : ClassMap<Product>
{
    public ProductMap()
    {
        Table("Products");
        Id(x => x.ProductId);
        References(x => x.Category).Column("CategoryId");
    }
}

public class CategoryMap : ClassMap<Category>
{
    public CategoryMap()
    {
        Table("Categories");
        Id(x => x.CategoryId);
        HasMany(x => x.Products).KeyColumn("ProductId");
    }
}

Я заметил следующее в сгенерированной вставке NHibernate выше:

CategoryId и Categoryid не совпадают. Обратите внимание на Id и id в конце.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...