Разработка БД, в которой первичный ключ таблицы также является внешним ключом другой таблицы - PullRequest
0 голосов
/ 27 января 2020

Я пытаюсь найти лучший способ создать свою базу данных. У меня есть 2 таблицы, Product и Image.

Продукт

PId PRIMARY KEY IDENTITY(1, 1)
PName
PPrice

Изображение

PId PRIMARY KEY IDENTITY(1,1)
PImage1 
PImage2
FOREIGN KEY (PId) REFERENCES Product(PId)

В настоящее время моя база данных разработана неправильно. Поскольку я предполагаю, что всякий раз, когда добавляется запись в Product, сразу после добавления в Image. Это предположение также делает предположение, что сгенерированный первичный ключ для Image такой же, как сгенерированный первичный ключ для Product.

Тогда в коде контроллера у меня есть:

_context.Product.Add(Product); // Add the created product record to the database

await _context.SaveChangesAsync();

_context.Image.Add(imageRecord); // Add the created image record to the database.

await _context.SaveChangesAsync();

где соответственно Product и imageRecord являются объектами следующих классов моделей:

public class Product
{
    public int ProductID { get; set; }
    public string ProductName { get; set; }
    public string ProductShortDesc { get; set; }
    public string ProductLongDesc { get; set; }
    public decimal ProductPrice { get; set; }
}

public class Image
{
    [ForeignKey("Product")]
    [Key]
    public int ProductID { get; set; }
    public byte[] ProductImage1 { get; set; }
    public byte[] ProductImage2 { get; set; }
    public byte[] ProductImage3 { get; set; }
}

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

Как я могу разработать его лучше, чтобы я мог выбрать первичный ключ Product, что позволит мне использовать его в качестве первичного ключа Image?

Ответы [ 3 ]

0 голосов
/ 28 января 2020

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

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

Более того, вы также можете жить с одной таблицей. Причиной создания двух таблиц является наличие отношения от 1 до N. Таблицы также очень малы с точки зрения ширины.

0 голосов
/ 28 января 2020

Рекомендую хранить картинки в файловой системе сервера. Я также рекомендовал бы создать одну таблицу с изображениями.

public class Product
{
    [Key]
    public int ProductID { get; set; }
    public string ProductName { get; set; }
    public string ProductShortDesc { get; set; }
    public string ProductLongDesc { get; set; }
    public decimal ProductPrice { get; set; }

    public Icollection<Image> Images { get; set; }
}

public class Image
{        
    [Key]
    public int ImageId { get; set; }
    public int ProductId { get; set; }
    public stirng ImageName { get; set; }

    [ForeignKey("ProductID")]
    public Product Product { get; set; }
}

Теперь, чтобы получить изображение, достаточно выполнить запрос на PruductId из таблицы изображений.

В будущем это позволит вам легко изменить количество изображений. Это также ускорит работу вашего приложения, потому что вам не нужно анализировать изображение.

0 голосов
/ 28 января 2020

Ниже приведена демонстрация, в которой Product и Image имеют отношения один-к-одному.

Image установил ProductID как PK, так и FK.

Затем добавьте атрибут [DatabaseGenerated(DatabaseGeneratedOption.None)] в Image.ProductID, чтобы установить значение PK вручную вместо автоматического увеличения.

public class Product
{
    [Key]
    public int ProductID { get; set; }
    public string ProductName { get; set; }
    public string ProductShortDesc { get; set; }
    public string ProductLongDesc { get; set; }
    public decimal ProductPrice { get; set; }
    public Image Image { get; set; }
}

public class Image
{        
    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.None)]
    public int ProductID { get; set; }
    public byte[] ProductImage1 { get; set; }
    public byte[] ProductImage2 { get; set; }
    public byte[] ProductImage3 { get; set; }

    [ForeignKey("ProductID")]
    public Product Product { get; set; }
}

контроллер:

_context.Products.Add(Product);
await _context.SaveChangesAsync();

var imageRecord = new Image()
{
     ProductID = Product.ProductID,
     ProductImage1 = xxx,
     //other properties
};
_context.Images.Add(imageRecord); // Add the created image record to the database.

await _context.SaveChangesAsync();

Наконец, вы создадите два объекта с одинаковым значением PK и будет использовано каскадное удаление.

...