实体集的关键 - 实体框架

问题描述 投票:0回答:1

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

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

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

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

是否有另一种方法来定义Item类的键?

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

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

MyStoreProject.Dal.Item :: EntityType'Item'没有定义键。定义此EntityType的键。 items:EntityType:EntitySet'itements'基于没有定义键的类型'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个回答
0
投票

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

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

例如:

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之间的关系而不需要productId,但您可以进一步阅读。

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

© www.soinside.com 2019 - 2024. All rights reserved.