Ключ для набора сущностей - Entity Framework - PullRequest
0 голосов
/ 28 апреля 2019

Я пытаюсь вернуть некоторые значения из базы данных, и у меня есть два класса Item и Product.Item содержит поля Product и quantity.

В базе данных есть таблица с именем Items.Как правильно использовать DbContext?

Потому что, когда я пытаюсь вызвать базу данных, я получаю сообщение об ошибке

MyStoreProject.Dal.Item: EntityType«Элемент» не имеет определенного ключа.Определите ключ для этого EntityType.
items: EntityType: EntitySet 'items' основан на типе 'Item', для которого не определены ключи.

Есть ли другой способ определить ключ дляItem класс?

Я уже пытался найти правильный путь ... поэтому, пожалуйста, помогите

System.Data.Entity.ModelConfiguration.ModelValidationException
HResult =0x80131500
Сообщение = Одна или несколько ошибок проверки были обнаружены во время генерации модели:

MyStoreProject.Dal.Item:: EntityType 'Item' не определен ключ.Определите ключ для этого EntityType.
items: EntityType: EntitySet 'items' основан на типе 'Item', для которого не определены ключи.

Код:

public class ItemDal : DbContext
{
    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        base.OnModelCreating(modelBuilder);
        modelBuilder.Entity<Item>().ToTable("Items");
    }
    public DbSet<Item> items { get; set; }
}

public class Item
{
    [Key]
    public Product idproduct { get; set; }
    [Required]
    public int quantity { get; set; }
}

public class Product
{
    [Key]
    [Required]
    [RegularExpression("^[0-9]{3}$", ErrorMessage = "Product ID must be with 4 numbers")]
    public string productId { get; set; }

    [RegularExpression("^[a-z]+$", ErrorMessage = "Product Name must be only Characters")]
    [StringLength(50, MinimumLength = 2, ErrorMessage = "Product Name must be with a least 2 Characters or Maximum 10 Characters")]
    public string name { get; set; }

    [Required]
    public string description { get; set; }

    [Required]
    [RegularExpression("^[0-9]{3}$", ErrorMessage = "Price can be with 3 numbers")]
    public float price { get; set; }

    [Required]
    [RegularExpression("^[0-9]{3}$", ErrorMessage = "Class Code can be Only between 1-20")]
    public int classCode { get; set; }

    public string image { get; set; }
}

А вот код с исключением

ItemDal itemDal = new ItemDal();

Item dbitem = (from x in itemDal.items
               where x.idproduct.productId.Equals(id)
               select x).ToList<Item>().FirstOrDefault();

1 Ответ

0 голосов
/ 29 апреля 2019

Думайте о сущностях так же, как о таблице в базе данных.Если Item является сущностью, то он должен соответствовать таблице в базе данных.Вы указали, что первичным ключом для «Item» является сущность Product.Это все равно что пытаться настроить таблицу Item с PK на таблицу Product.Не работает таким образом.

Если Item совместно использует PK с Product, т.е. productId, то сущность Item также нуждается в свойстве productId, чтобы установить свой атрибут [Key].Элемент также может иметь свойство Product, которое отображается как 1-к-1, используя этот productId в качестве FK.

Например:

public class Item
{
    [Key]
    [ForeignKey("idProduct")]
    public string productId { get; set; }

    public virtual Product idProduct { get; set; }
}

Чтобы извлечь элемент по идентификатору продукта:

var item = itemDal.items.SingleOrDefault(x => x.productId == id);

Для включения сведений о продукте:

var item = itemDal.items.Include(x => x.idProduct).SingleOrDefault(x => x.productId == id);

Если у элемента есть собственный ключ (itemId), определите его как [Key] и сохраните productId как внешний.ключ.Это устанавливает отношение многих к 1.(многие товары могут ссылаться на один и тот же товар)

public class Item
{
    [Key]
    public string itemId { get; set; }
    [ForeignKey("idProduct")]
    public string productId { get; set; }

    public virtual Product idProduct { get; set; }
}

Затем получить первый (произвольный) товар для товара:

var item = itemDal.items.FirstOrDefault(x => x.productId == id);
// or...
var item = itemDal.items.FirstOrDefault(x => x.idProduct.productId == id);

В этом случае вы можете настроить связь между товароми Product без использования productId в объекте item с использованием явного сопоставления (EF6) или свойства shadow (EF Core), но вы можете прочитать об этом подробнее.

Это хорошо, если вы просто хотите получить информацию отданные.Если вы хотите вернуть данные в представление или что-либо подобное вне области действия DbContext (itemDal), то лучше всего использовать .Select() для заполнения простого класса только необходимыми деталями, а не просто / лениво загружать целые объекты,Как правило, не пропускайте сущности за пределы их DbContext (т. Е. Блока using() для контекста), так как это будет иметь последствия для отложенной загрузки.Объекты также создают проблемы для сериализаторов, такие как попытки вернуть их из действий контроллера MVC для представлений.Преимущество использования .Select() заключается в том, что вам не нужно беспокоиться о явном использовании .Include() для доступа к связанным данным.Он обеспечивает повышение производительности, поскольку уменьшает объем данных для загрузки и передачи, а также ограничивает информацию о вашей схеме, которая отправляется пользователю / потребителю.

...