【问题标题】:Key for entity set - Entity Framework实体集的关键 - 实体框架
【发布时间】:2019-04-28 11:11:11
【问题描述】:

我正在尝试从数据库中返回一些值,并且我有两个类ItemProductItem 包含一个 Productquantity 字段。

在数据库中,有一个名为Items 的表。 DbContext的正确使用方法是什么?

因为当我尝试调用数据酶时,我收到了一个错误

MyStoreProject.Dal.Item:EntityType 'Item' 没有定义键。定义此 EntityType 的键。
items: EntityType: EntitySet 'items' 基于没有定义键的类型 'Item'。

还有其他方法可以为Item 类定义键吗?

我已经尝试找到正确的方法...所以请您帮忙

System.Data.Entity.ModelConfiguration.ModelValidationException
HResult=0x80131500
Message=在模型生成期间检测到一个或多个验证错误:

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();

【问题讨论】:

    标签: entity-framework sqlite model-view-controller dbcontext


    【解决方案1】:

    将实体想象成数据库中的表。如果 Item 是一个实体,那么它应该与数据库中的一个表相关联。您已指定“Item”的主键是 Product 实体。这就像尝试将带有 PK 的 Item 表设置为 Product 表。那样不行。

    如果 Item 与 Product 共享一个 PK,即productId 然后 Item 实体也需要作为 productId 属性来设置它的 [Key] 属性。一个项目也可以有一个 Product 属性,该属性使用该 productId 作为 FK 进行一对一映射。

    例如:

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

    按产品 ID 获取项目:

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

    也包括产品详细信息:

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

    如果 Item 有自己的键 (itemId),则将其定义为 [Key] 并将 productId 保留为外键。这建立了多对一的关系。 (许多项目可能引用相同的产品)

    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);
    

    在这种情况下,您可以使用显式映射 (EF6) 或影子属性 (EF Core) 来配置 Item 和 Product 之间的关系,而无需 item 实体中的 productId,但您可以进一步阅读。

    如果您只想从数据中获取信息,这一切都很好。如果您想将数据返回到 DbContext (itemDal) 范围之外的视图等,那么您最好使用 .Select() 来填充一个简单的类,其中包含您需要的详细信息,而不是急切/懒惰地加载整个实体.作为一般规则,不要将实体传递到其 DbContext 范围之外(即上下文的 using() 块),因为这将对延迟加载产生影响。实体也会给序列化程序带来问题,例如尝试从 MVC 控制器操作返回它们以获取视图。使用.Select() 的好处是您无需担心显式使用.Include() 来访问相关数据。它为您提供了性能改进,因为它减少了要加载和传输的数据量,并且还限制了发送给用户/消费者的架构信息。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-07-11
      • 2017-07-20
      • 2023-04-02
      • 1970-01-01
      相关资源
      最近更新 更多