Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/mercurial/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Entity framework core 在实体框架内核中实现ADO.NET设计_Entity Framework Core - Fatal编程技术网

Entity framework core 在实体框架内核中实现ADO.NET设计

Entity framework core 在实体框架内核中实现ADO.NET设计,entity-framework-core,Entity Framework Core,我一直在学习ADO.NET,然后是EF Core。我的任务是在C#中创建一个数据库应用程序,首先在ADO.NET中创建,然后将该应用程序转换为实体框架 这是我在ADO.NET中的设计,看起来效果不错 CREATE TABLE Categories ( Id INT IDENTITY, Name NVARCHAR(50) NOT NULL, CONSTRAINT PK_Categories PRIMARY KEY (Id) ) CREATE TABLE C

我一直在学习ADO.NET,然后是EF Core。我的任务是在C#中创建一个数据库应用程序,首先在ADO.NET中创建,然后将该应用程序转换为实体框架

这是我在ADO.NET中的设计,看起来效果不错

CREATE TABLE Categories (
    Id INT IDENTITY,
    Name NVARCHAR(50) NOT NULL,
    CONSTRAINT PK_Categories
        PRIMARY KEY (Id)
)

CREATE TABLE CategoryCategories (
    ParentCategoryId INT,
    ChildCategoryId INT,
    CONSTRAINT PK_CategoryCategories
        PRIMARY KEY (ParentCategoryId, ChildCategoryId),
    CONSTRAINT FK_CategoryCategories_ParentCategoryId
        FOREIGN KEY (ParentCategoryId)
        REFERENCES Categories (Id),
    CONSTRAINT FK_CategoryCategories_ChildCategoryId
        FOREIGN KEY (ChildCategoryId)
        REFERENCES Categories (Id)
    ON DELETE CASCADE
)

CREATE TABLE Products (
    Id INT IDENTITY,
    ArticleNumber NVARCHAR(50) NOT NULL UNIQUE,
    Name NVARCHAR(50) NOT NULL,
    Description NVARCHAR(500) NOT NULL,
    Price DECIMAL(18,2) NOT NULL,
    CONSTRAINT PK_Products
        PRIMARY KEY (Id)
);

CREATE TABLE Products_Categories (
    ProductId INT,
    CategoryId INT NOT NULL,
    CONSTRAINT PK_Products_Categories
        PRIMARY KEY (ProductId, CategoryId),
    CONSTRAINT FK_ProdCats_Prods
        FOREIGN KEY (ProductId)
        REFERENCES Products (Id),
    CONSTRAINT FK_ProdCats_Cats
        FOREIGN KEY (CategoryId)
        REFERENCES Categories (Id)
    ON DELETE CASCADE
);
产品和类别之间的连接——没问题,只是两个响应类中每个类的ICollection属性。实体框架立即创建了CategoryProducts连接表

当在实体和自身之间创建连接时,我遇到了一堵墙。我试图简单地将迁移生成的CategoryProducts的所有模型构建代码复制到CategoryCategories的OnModelCreating方法中,并插入正确的列和表名称

不起作用,有人抱怨CategoryCategories处于阴影模式。我已经用吸尘器清理了互联网,试图找到一个解决方案,但我找不到任何清晰的说明。在实体框架中实现这一点真的比在常规SQL或ADO.NET中困难得多吗?我认为实体框架应该让事情变得更简单

有什么建议吗?如果你需要更多的信息,请告诉我

编辑

为了清晰起见,我想我可以添加这些类

    class Category
    {
        public int Id { get; protected set; }
        [Required]
        public string Name { get; protected set; }

        public ICollection<Product> Products { get; protected set; }
        // public ICollection<Category> ChildCategories { get; protected set; }
        public Category(string name)
        {
            Name = name;
            Products = new List<Product>();
            // ChildCategories = new List<Category>();
        }
    }

class CategoryCategory
    {
        // EFC forced me to have an Id. Could not run Add-migr Initial without it
        public int Id { get; protected set; }
        [Required]
        public int ParentCategoryId { get; protected set; }
        [Required]
        public int ChildCategoryId { get; protected set; }
        public CategoryCategory(int parentCategoryId, int childCategoryId)
        {
            ParentCategoryId = parentCategoryId;
            ChildCategoryId = childCategoryId;
        }
    }

    class Product
    {
        public int Id { get; protected set; }
        [Required]
        public string ArticleNumber { get; protected set; }
        [Required]
        // EFC forcing me to have unprotected set
        // Without it, I can not update articles :(
        public string Name { get; set; }
        [Required]
        public string Description { get; set; }
        [Required]
        public decimal Price { get; set; }

        public ICollection<Category> Categories { get; protected set; }

        public Product(string articleNumber, string name, string description, decimal price)
        {
            ArticleNumber = articleNumber;
            Name = name;
            Description = description;
            Price = price;
            Categories = new List<Category>();
        }

        public Product(int id, string articleNumber, string name, string description, decimal price)
            : this(articleNumber, name, description, price)
        {
            Id = id;
        }
    }
类别
{
public int Id{get;protected set;}
[必需]
公共字符串名称{get;protected set;}
公共ICollection产品{get;protected set;}
//公共ICollection子类别{get;protected set;}
公共类别(字符串名称)
{
名称=名称;
产品=新列表();
//ChildCategories=新列表();
}
}
类范畴
{
//EFC强制我拥有一个Id。没有它,无法运行Add migr Initial
public int Id{get;protected set;}
[必需]
public int ParentCategoryId{get;protected set;}
[必需]
public int ChildCategoryId{get;protected set;}
公共类别类别(int parentCategoryId、int childCategoryId)
{
ParentCategoryId=ParentCategoryId;
ChildCategoryId=ChildCategoryId;
}
}
类产品
{
public int Id{get;protected set;}
[必需]
公共字符串ArticleNumber{get;protected set;}
[必需]
//EFC强制我设置未受保护的
//没有它,我无法更新文章:(
公共字符串名称{get;set;}
[必需]
公共字符串说明{get;set;}
[必需]
公共十进制价格{get;set;}
公共ICollection类别{get;protected set;}
公共产品(字符串编号、字符串名称、字符串描述、十进制价格)
{
ArticleNumber=ArticleNumber;
名称=名称;
描述=描述;
价格=价格;
类别=新列表();
}
公共产品(int-id、string-articleNumber、string-name、string-description、十进制价格)
:此(商品编号、名称、说明、价格)
{
Id=Id;
}
}
对于这些类,EF表示实体类型“CategoryCategories”处于阴影状态。有效的模型要求所有实体类型都具有相应的CLR类型

如果我取消对Category中ICollection ChildCategories部分的注释,那么EF将在CategoryCategories中创建第三列CategoryId,这在我看来是非常不可取的。既然我已经有两个类别,为什么我还希望第三个ID引用类别

产品和类别之间的连接——没问题,只是两个响应类中每个类的ICollection属性。实体框架立即创建了CategoryProducts连接表

如果这是可行的,那么您将使用EF Core 5.0+,它增加了对隐式连接实体的多对多关系的支持,可以看出,创建这样的关系非常容易

但是您的
类别类别
表示完全相同类型的关系,唯一的区别是,两个相关的端点是一个相同的实体

那么如何在两个实体之间创建这种关系呢?可以通过在每个相关实体中添加2个(!)集合导航属性来实现:

class Product
{
    public ICollection<Category> Categories { get; set; }
}

class Category
{
    public ICollection<Product> Products { get; set; }
}
如果您不喜欢生成的表/列名,它们都可以通过fluent API进行配置。如果您喜欢,您甚至可以创建和映射显式连接实体,并且仍然可以使用所谓的“跳过导航”的好处


但是,这两个集合导航属性是最基本的属性,是使EF核心方法更简单的东西。

实体与自身之间的连接的目的是什么?顺便问一下,EF使它更容易-只要需求明确。目的是创建上表的CategoryCategories。或者更确切地说,让EF创建它。正如我所说的,我想在EF中复制ADO.NET设计,因此EF表的结构将与第一个表(ADO.NET)完全相同一个。正如你所看到的,它有两个外键都指向go类别。非常感谢!我想这解决了它。不知道我做错了什么,导致了这个额外的类别,但现在一切似乎都很好,所以这是没有意义的。再次感谢。
class Category
{
    public ICollection<Category> ParentCategories { get; set; }
    public ICollection<Category> ChildCategories { get; set; }
}
migrationBuilder.CreateTable(
    name: "CategoryCategory",
    columns: table => new
    {
        ChildCategoriesId = table.Column<int>(type: "int", nullable: false),
        ParentCategoriesId = table.Column<int>(type: "int", nullable: false)
    },
    constraints: table =>
    {
        table.PrimaryKey("PK_CategoryCategory", x => new { x.ChildCategoriesId, x.ParentCategoriesId });
        table.ForeignKey(
            name: "FK_CategoryCategory_Categories_ChildCategoriesId",
            column: x => x.ChildCategoriesId,
            principalTable: "Categories",
            principalColumn: "Id",
            onDelete: ReferentialAction.Cascade);
        table.ForeignKey(
            name: "FK_CategoryCategory_Categories_ParentCategoriesId",
            column: x => x.ParentCategoriesId,
            principalSchema: "SO14",
            principalTable: "Categories",
            principalColumn: "Id",
            onDelete: ReferentialAction.Restrict);
    });