Entity Framework教程-Entity Framework-模型关系(Model Relationships)

news/2024/5/6 17:23:44/文章来源:https://www.cnblogs.com/cqpanda/p/16783493.html

更新记录
转载请注明出处:
2022年10月17日 发布。
2022年10月10日 从笔记迁移到博客。

配置实体关系的方式

使用数据特性
使用FluentAPI关系配置
使用关系属性

导航属性(navigation property)

导航属性说明

一个类型为主体实体或从属实体的属性

无论它是指它的父实体还是持有一个或多个从属实体

都被称为导航属性(navigation property)

导航属性分类

说明

集合型导航属性(Collection navigation property)

引用型导航属性(Reference navigation property)

反向引用导航属性(Inverse navigation property)

集合型导航属性(Collection navigation property)

集合型导航属性保存一个依赖实体的集合(或对依赖项列表的引用)

并且始终保存对多个项的引用

//博客实体
class Blog
{//主键[Key]public int Id { get; set; }public string Title { get; set; }//集合导航属性//评论属性public ICollection<Post> Posts { get; set; }
}

引用型导航属性(Reference navigation property)

引用型导航属性保存对其父实体的引用,并且始终保存对单个项的引用

//评论实体
public class Post
{//其他代码...public int BlogId { get; set; }//引用型导航属性//关联的blog实体public Blog Blog { get; set; }
}

反向引用导航属性(Inverse navigation property)

EF Core模型间关联(Modeling Relationships)

EF Core关联的默认约定(Conventions in a relationship)

定义两个实体之间的关系时,在两个实体内部都需要定义关联导航属性

并且从属实体应具有外键属性

如果这两个实体的导航属性相互指向,EF会将它们配置为反向导航属性

两实体都定义导航属性的实体关系叫做完全定义的关系(Fully-defined relationships)

//博客实体
public class Blog
{//定义集合导航属性public ICollection<Post> Posts { get; set; }    
}//评论实体
public class Post
{//外键属性public int BlogId { get; set; }//反向导航属性public Blog Blog { get; set; }
}

如果使用主键属性名的主体实体名,EF将认为该属性为外键

public class Blog
{public int Id { get; set; }
}public class Post
{public int BlogId { get; set; }
}

如果主体实体主键与依赖实体引用键匹配,EF将创建外键关系

public class Blog
{public int Id { get; set; }
}public class Post
{public Blog SomeBlog { get; set; }public int SomeBlogId { get; set; }  //外键字段
}

注意:如果我们不创建外键字段,EF Core仍然会在底层自动创建

public class Blog
{public int Id { get; set; }
}public class Post
{public Blog SomeBlog { get; set; }
}

注意:如果我们把外键关联属性也删除了,EF Core仍然会在底层自动创建外键字段

public class Blog
{public ICollection<Post> Posts { get; set; }    
}public class Post
{//仍会创建外键字段
}

注意:如果实体间包含多个关联,还是需要自己设置反向关联

public class Blog
{[InverseProperty("SomeBlog")]public ICollection<Post> SomePosts { get; set; }
}public class Post
{public int SomeBlogId { get; set; }public Blog SomeBlog { get; set; }
}

EF Core手动设置外键底层字段

除了使用EF默认的关联约定,还可以自己设置底层的外键字段

使用ForeignKey数据注解即可

public class Blog
{public ICollection<Post> Posts { get; set; }    
}public class Post
{public int BlogSomeId { get; set; }//手动设置外键底层字段[ForeignKey("BlogSomeId")]public Blog Blog { get; set; }
}

Fluent API配置关系的方法

HasXXX(...).WithXXX(...);

有XXX、反之带有XXX。XXX可选值One、Many。

HasOne(...).WithMany(...);		//一对多
HasOne(...).WithOne (...);		//一对一
HasMany(...).WithMany(...);		//多对多

注意:不设置反向的属性的时候,Withxxxx()不设置参数即可。

技巧:

1.关系配置在任何一方都可以。

2.对于主从结构的“一对多”表关系,一般是声明双向导航属性。而对于其他的“一对多”表关系:如果表属于被很多表引用的基础表,则用单项导航属性,否则可以自由决定是否用双向导航属性。

3.对于一对一的关系,使用[ForeignKey]特性标注存储外键的关联属性,或者专门定义一个外键属性,或者使用FluentAPI。

builder.HasOne<Delivery>(o => o.Delivery).WithOne(d =>d.Order).HasForeignKey<Delivery>(d=>d.OrderId);

设置外键属性

1、在实体类中显式声明一个外键属性。
2、关系配置中通过HasForeignKey(c=>c.ArticleId)指定这个属性为外键。
3、除非必要,否则不用声明,因为会引入重复。

设置一对一(One-to-one relationships)-使用默认约定

设置方法

在两个实体对象中建立引用属性,然后添加外键属性即可

注意:务必将两个实体都加上[Key]主键修饰,否则无法设置一对一

本质是:在子表内设置外键字段,并将该字段设置为唯一

引用数据的实体(数据库中的子表)(引用数据方):

Public 被引用Model名 被引用Model名 { get; set; }public int? 被引用Model名Id { get; set; }

被引用数据的实体模型(数据库中的母表)(被引用数据方):

public 引用Model名 引用Model名 { get; set; }

实例:一个人只能有一个身份证卡(一对一)(Fluent API)

IdCard.cs Id卡实体

using Microsoft.EntityFrameworkCore;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.ComponentModel.Design;namespace PandaTest
{/// <summary>/// Id卡/// </summary>public class IdCard{[Key]public Guid Id { get; set; }public string? Name { get; set; }[ForeignKey("PersonId")]public Person? Person { get; set; }}
}

IdCardEntityConfig.cs Id卡实体配置

using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;namespace PandaTest
{/// <summary>/// 人员实体配置/// </summary>public class IdCardEntityConfig : IEntityTypeConfiguration<IdCard>{public void Configure(EntityTypeBuilder<IdCard> builder){}}
}

Person.cs 人员实体

using Microsoft.EntityFrameworkCore;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.ComponentModel.Design;namespace PandaTest
{/// <summary>/// 人员实体/// </summary>public class Person{[Key]public Guid Id { get; set; }public string? Name { get; set; }public IdCard? IdCard { get; set; }}
}

PersonEntityConfig.cs 人员实体配置

using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;namespace PandaTest
{/// <summary>/// 人员实体配置/// </summary>public class PersonEntityConfig : IEntityTypeConfiguration<Person>{public void Configure(EntityTypeBuilder<Person> builder){//建立一对一的关联builder.HasOne(i => i.IdCard).WithOne(i => i.Person);}}
}

TestDbContext.cs 数据库上下文

using Microsoft.EntityFrameworkCore;
using System.Diagnostics;namespace PandaTest
{/// <summary>/// 数据库上下文/// </summary>public class TestDbContext: DbContext{public TestDbContext(){}protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder){string connectionString = "Server=.;Database=Test;User Id=sa;Password=Password";optionsBuilder.UseSqlServer(connectionString);optionsBuilder.LogTo(x => { Debug.WriteLine(x); });}protected override void OnModelCreating(ModelBuilder modelBuilder){base.OnModelCreating(modelBuilder);//应用所有实体配置modelBuilder.ApplyConfigurationsFromAssembly(this.GetType().Assembly);}public DbSet<Person> Persons { get; set; }public DbSet<IdCard> IdCards { get; set; }}
}

Program.cs 主程序

using PandaTest;
using Microsoft.EntityFrameworkCore;Console.WriteLine("Begin");//创建DbContext
using (TestDbContext db = new TestDbContext())
{var Panda = new Person{Name = "Panda",IdCard = new IdCard() { Name = "PandaIdCard" }};//插入数据db.Persons.Add(Panda);await db.SaveChangesAsync();
}Console.WriteLine("Success");

实例:一个人只能有一个对象(一对一)(自引用)(Fluent API)

Person.cs 人员实体

using Microsoft.EntityFrameworkCore;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.ComponentModel.Design;namespace PandaTest
{/// <summary>/// 人员实体/// </summary>public class Person{[Key]public Guid Id { get; set; }public string? Name { get; set; }[ForeignKey("OtherHalfId")]public virtual Person? OtherHalf { get; set; }}
}

PersonEntityConfig.cs 人员实体配置

using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;namespace PandaTest
{/// <summary>/// 人员实体配置/// </summary>public class PersonEntityConfig : IEntityTypeConfiguration<Person>{public void Configure(EntityTypeBuilder<Person> builder){}}
}

TestDbContext.cs 数据库上下文

using Microsoft.EntityFrameworkCore;
using System.Diagnostics;namespace PandaTest
{/// <summary>/// 数据库上下文/// </summary>public class TestDbContext: DbContext{public TestDbContext(){}protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder){string connectionString = "Server=.;Database=Test;User Id=sa;Password=Password";optionsBuilder.UseSqlServer(connectionString);optionsBuilder.LogTo(x => { Debug.WriteLine(x); });}protected override void OnModelCreating(ModelBuilder modelBuilder){base.OnModelCreating(modelBuilder);//应用所有实体配置modelBuilder.ApplyConfigurationsFromAssembly(this.GetType().Assembly);}public DbSet<Person> Persons { get; set; }}
}

Program.cs 主程序

using PandaTest;
using Microsoft.EntityFrameworkCore;Console.WriteLine("Begin");//创建DbContext
using (TestDbContext db = new TestDbContext())
{var Panda = new Person{Name = "Panda",};var Donkey = new Person{Name = "Donkey",OtherHalf = Panda};//插入数据db.Persons.Add(Donkey);await db.SaveChangesAsync();var panda = db.Persons.Where(i => i.Name == "Panda").FirstOrDefault();panda.OtherHalf = Donkey;db.Persons.Update(panda);await db.SaveChangesAsync();
}Console.WriteLine("Success");

实例:用户 和 户籍地址

一个用户 只有 一个户籍地址

一个户籍地址 只对应 一个用户

image

代码:

using System;
using System.ComponentModel.DataAnnotations;namespace ConsoleApp3.Models
{public class Address{[Key]public int Id { get; set; }public string Description { get; set; }//外键public int UserId { get; set; }//关联用户模型public User User { get; set; }}
}
using System;
using System.ComponentModel.DataAnnotations;namespace ConsoleApp3.Models
{public class User{[Key]public int Id { get; set; }public string Name { get; set; }//关联地址模型public Address Address { get; set; }}
}

实例:用户 和 颜色

一个用户 有且只有 一个颜色

一个颜色 有且只对应 一个用户

image

代码:

颜色实体Entity:

class Color
{[Key]public int ColorId { get; set; }public string ColorTitle { get; set; }public User User { get; set; }   //重点
}

用户实体Entity:

class User
{[Key]public int UserId { get; set; }public string UserName { get; set; }public Color Color { get; set; }public int? ColorId { get; set; }
}

设置一对一(One-to-one relationships)-使用FluentAPI

设置方法

本质是:在子表内设置外键字段,并将该字段设置为唯一

protected override void OnModelCreating(ModelBuilder modelBuilder)
{//设置外键关联modelBuilder.Entity<User>().HasOne(x => x.Address) //设置关联到另一个唯一的实体.WithOne(x => x.User)   //配置一对一的关系.HasForeignKey<Address>(x => x.UserId); //配置外键
}

实例:用户 和 户籍地址

一个用户 只有 一个户籍地址

一个户籍地址 只对应 一个用户

image

代码:

using System;
using System.ComponentModel.DataAnnotations;namespace ConsoleApp3.Models
{public class Address{[Key]public int Id { get; set; }public string Description { get; set; }public User User { get; set; }public int UserId { get; set; }}
}
using System;
using System.ComponentModel.DataAnnotations;namespace ConsoleApp3.Models
{public class User{[Key]public int Id { get; set; }public string UserName { get; set; }public int Age { get; set; }public Address Address { get; set; }}
}
protected override void OnModelCreating(ModelBuilder modelBuilder)
{//设置映射到底层数据库的表名modelBuilder.Entity<Address>().ToTable("AddressTable");//设置外键关联modelBuilder.Entity<User>().ToTable("UserTable")  //设置映射到底层数据库的表名.HasOne(x => x.Address) //设置关联到另一个唯一的实体.WithOne(x => x.User)   //配置一对一的关系.HasForeignKey<Address>(x => x.UserId); //配置外键
}

实例:学生 和 学生地址

一个学生 对应一个 学生地址

一个学生地址 对应一个 学生

学生实体:

//学生实体
public class Student
{public int Id { get; set; }public string Name { get; set; }//导航属性public StudentAddress Address { get; set; }
}

学生地址实体:

//学生地址实体
public class StudentAddress
{public int StudentAddressId { get; set; }public string Address { get; set; }//外键导航属性public int AddressOfStudentId { get; set; }//导航属性public Student Student { get; set; }
}

配置一对一关系:

//配置一对一关系
protected override void OnModelCreating(ModelBuilder modelBuilder)
{modelBuilder.Entity<Student>().HasOne(s => s.Address).WithOne(d => d.Student).HasForeignKey<StudentAddress>(d => d.StudentAddressId);
}

image

除了可以在Student实体上配置,还可以在StudentAddress实体上配置:

protected override void OnModelCreating(ModelBuilder modelBuilder)
{modelBuilder.Entity<StudentAddress>().HasOne<Student>(d => d.Student).WithOne(s => s.Address).HasForeignKey<StudentAddress>(d => d.AddressOfStudentId);
}

生成的数据库如同所示:

image

设置一对多(One-to-many relationships)-使用默认约定

设置方法1(EF约定1)- 单方设置引用属性

直接在单个实体模型中定义引用

//学生
public class Student
{public int Id { get; set; }public string Name { get; set; }//关联的年级public Grade Grade { get; set; }
}
//年级
public class Grade
{public int GradeId { get; set; }public string GradeName { get; set; }public string Section { get; set; }
}

这种方式最终在数据库中的表会生成一个外键字段

image

注意:

这种方式生成的外键字段GradeId是可以为null的

可以通过FluentAPI设置其禁止为NULL

设置方法2(EF约定2)- 多方设置引用

//学生实体
public class Student
{public int StudentId { get; set; }public string StudentName { get; set; }
}
//年级实体
public class Grade
{public int GradeId { get; set; }public string GradeName { get; set; }public string Section { get; set; }//关联多个学生public ICollection<Student> Students { get; set; } 
}

image

设置方法3(EF约定3)- 双方都建立引用属性

本质就是:约定1+约定2

//学生实体
public class Student
{public int Id { get; set; }public string Name { get; set; }//引用属性public Grade Grade { get; set; }
}
//年级实体
public class Grade
{public int GradeID { get; set; }public string GradeName { get; set; }//集合引用属性public ICollection<Student> Students { get; set; }
}

image

设置方法4(EF约定4)- 设置额外的外键属性

在约定3的基础上再增加 外键字段属性

//学生实体
public class Student
{public int Id { get; set; }public string Name { get; set; }//外键字段属性public int GradeId { get; set; }//引用属性public Grade Grade { get; set; }
}
//年级实体
public class Grade
{public int GradeId { get; set; }public string GradeName { get; set; }//集合引用属性public ICollection<Student> Students { get; set; }
}

image

注意:

这种方式定义的数据库的表的外键字段是不可以为Null的

​ 如果需要字段是可以为NULL的,请使用:

public int? GradeId { get; set; } 

实例:用户 和 产品

一个用户 对应 多个产品

一个产品 对应 一个用户

image

产品Entity:

class Product
{[Key]public int ProdcutId { get; set; }public string ProductTitle { get; set; }public decimal Price { get; set; }public virtual User User { get; set; }[ForeignKey("UserId")]public int? UserId { get; set; }
}

用户实体Entity:

class User
{[Key]public int UserId { get; set; }public string UserTitle { get; set; }public int age { get; set; }public virtual ICollection<Product> Products { get; set; } = new List<Product>();
}

实例:用户 和 车

一个用户 对应 多台车

一台车 只属于 一个用户

image

用户实体Entity:

class User
{public int UserId { get; set; }[StringLength(100)]public string UserName { get; set; }public ICollection<Car> Cars { get; set; } = new List<Car>();
}

车实体Entity:

class Car
{public int CarId { get; set; }public string CarBrand { get; set; }public virtual User User { get; set; }  //重点[ForeignKey("UserId")]public int? UserId { get; set; }        //重点
}

实例:用户 和 用户自定义配置信息

一个用户 有多个 自定义配置信息

多个自定义配置信息 对应 一个用户

image

用户实体:

public class User
{[Key]public int Id { get; set; }public string Name { get; set; }public int Age { get; set; }public DateTime JoinDateTime { get; set; }public ICollection<Configuration> Configurations { get; set; }
}

配置项实体:

public class Configuration
{[Key]public int Id { get; set; }public string Code { get; set; }public string Title { get; set; }public string Description { get; set; }public virtual User BelongUser { get; set; }
}

实例:博客文章 和 评论

一篇博客 可以有 多条评论

多条评论 对应 一篇博客

image

代码:

评论实体模型:

using System;
using System.Collections.Generic;
using System.Text;
using System.ComponentModel.DataAnnotations;namespace ConsoleApp3.Models
{public class Post{[Key]public int Id { get; set; }public string Title { get; set; }public string Context { get; set; }public Blog Blog { get; set; }public int BlogId { get; set; }}
}

博客文章实体模型:

using System;
using System.Collections.Generic;
using System.Text;
using System.ComponentModel.DataAnnotations;namespace ConsoleApp3.Models
{public class Blog{[Key]public int Id { get; set; }public string Title { get; set; }public string Content { get; set; }public ICollection<Post> Posts { get; set; }}
}

设置一对多(One-to-many relationships)-使用FluentAPI

设置方法(EF约定)

创建实体模型:学生 和 年级

一个学生对应一个年级,一个年级有多个学生

学生实体:

public class Student
{public int Id { get; set; }public string Name { get; set; }//外键导航属性public int CurrentGradeId { get; set; }//导航属性public Grade Grade { get; set; }
}

年级实体:

public class Grade
{public int GradeId { get; set; }public string GradeName { get; set; }public string Section { get; set; }//集合导航属性public ICollection<Student> Students { get; set; }
}

定义FluentAPI

protected override void OnModelCreating(ModelBuilder modelBuilder)
{modelBuilder.Entity<Student>().HasOne<Grade>(s => s.Grade)    //(一)学生实体只有一个年级导航属性.WithMany(g => g.Students)      //(多)年级实体对应多个学生.HasForeignKey(s => s.CurrentGradeId);  //学生实体有一个外键导航属性
}

关系如图所示:

image

除了在学生实体上进行定义与年级实体的关联
还可以在年级实体上定义与学生实体的关联

protected override void OnModelCreating(ModelBuilder modelBuilder)
{modelBuilder.Entity<Grade>().HasMany<Student>(g => g.Students)  //(多)年级实体对应多个学生.WithOne(s => s.Grade)              //(一)学生实体只有一个年级导航属性.HasForeignKey(s => s.CurrentGradeId);   //学生实体有一个外键导航属性
}

实例:父亲 和 儿子

一个父亲 可以有 多个儿子

一个儿子 只有一个 亲生父亲

父亲实体:

//父亲实体
public class Father
{public int Id { get; set; }public string Name { get; set; }public int Age { get; set; }//集合导航属性public ICollection<Son> Sons { get; set; }
}

儿子实体:

//儿子实体
public class Son
{public int Id { get; set; }public string Name { get; set; }//外键导航属性public int FatherId { get; set; }//导航属性public Father Father { get; set; }
}

定义FluentAPI:

//定义FluentAPI
protected override void OnModelCreating(ModelBuilder modelBuilder)
{//定义一对多modelBuilder.Entity<Father>().HasMany(f => f.Sons).WithOne(s => s.Father).HasForeignKey(s => s.FatherId);
}

或者定义FluentAPI:

//定义FluentAPI
protected override void OnModelCreating(ModelBuilder modelBuilder)
{//定义多对一modelBuilder.Entity<Son>().HasOne(s => s.Father).WithMany(f => f.Sons).HasForeignKey(s => s.FatherId);
}

实例:一个人对应多台车(一对多)(Fluent API)

Car.cs 汽车实体

using System.ComponentModel.DataAnnotations;
using System.ComponentModel.Design;namespace PandaTest
{/// <summary>/// 汽车实体/// </summary>public class Car{public Guid Id { get; set; }public string CarName { get; set; }public Person BelongPerson { get; set; }}
}

Person.cs 人员实体

using Microsoft.EntityFrameworkCore;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.Design;namespace PandaTest
{/// <summary>/// 人员实体/// </summary>public class Person{public Guid Id { get; set; }public string Name { get; set; }public List<Car> Cars { get; set; }}
}

PersonEntityConfig.cs 人员实体配置

using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;namespace PandaTest
{/// <summary>/// 人员实体配置/// </summary>public class PersonEntityConfig : IEntityTypeConfiguration<Person>{public void Configure(EntityTypeBuilder<Person> builder){//配置关联(一个人有多台车,一个车只属于一个人)builder.HasMany(p => p.Cars).WithOne(c => c.BelongPerson);}}
}

CarEntityConfig.cs 汽车实体配置

using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;namespace PandaTest
{/// <summary>/// 汽车实体配置/// </summary>public class CarEntityConfig : IEntityTypeConfiguration<Car>{public void Configure(EntityTypeBuilder<Car> builder){}}
}

TestDbContext.cs 数据库上下文

using Microsoft.EntityFrameworkCore;namespace PandaTest
{/// <summary>/// 数据库上下文/// </summary>public class TestDbContext: DbContext{public TestDbContext(){}protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder){string connectionString = "Server=.;Database=Test;User Id=sa;Password=Password";optionsBuilder.UseSqlServer(connectionString);}protected override void OnModelCreating(ModelBuilder modelBuilder){base.OnModelCreating(modelBuilder);//应用所有实体配置modelBuilder.ApplyConfigurationsFromAssembly(this.GetType().Assembly);}public DbSet<Car> Cars { get; set; }public DbSet<Person> Persons { get; set; }}
}

Program.cs 主程序

using PandaTest;Console.WriteLine("Begin");//创建DbContext
using (TestDbContext db = new TestDbContext())
{//插入数据db.Persons.Add(new Person{Name = "Panda",Cars = new List<Car>{new Car(){Id = Guid.NewGuid(),CarName = "PandaCar1"},new Car(){Id = Guid.NewGuid(),CarName = "PandaCar2"}}});await db.SaveChangesAsync();
}Console.WriteLine("Success");

设置多对多(Many-to-many relationships)-使用默认约定

设置方法1(使用中间表)

折中方式,采用中间实体的形式实现,建立2个实体与中间实体的一对多的约定

多对多在数据库内部通过中间表的方式实现,所以需要添加一个中间Model

本质是:通过中间Model对两端Model的一对多的关系完成的

image

中间表Entity:

注意:还可以将CompanyId和 ConsumerId设置为Key,形成唯一pair

class ConsumerAndCompany
{[Key]public int ConsumerAndCompanyId { get; set; }[Required]public int CompanyId { get; set; }public virtual Company Company { get; set; }[Required]public int ConsumerId { get; set; }public virtual Consumer Consumer { get; set; }//建立客户关系的时间public DateTime ConnectionDateTime { get; set; }//建立客户关系的备注public String Note { get; set; }
}

Consumer Entity:

class Consumer
{[Key]public int ConsumerId { get; set; }public string ConsumerName { get; set; }public virtual List<ConsumerAndCompany> ConsumerAndCompanys { get; set; } = new List<ConsumerAndCompany>();
}

Company Entity:

class Company
{[Key]public int CompanyId { get; set; }public string CompanyName { get; set; }public virtual List<ConsumerAndCompany> CompanyAndConsumers { get; set; } = new List<ConsumerAndCompany>();
}

设置方法2(使用默认约定)

两个实体之间都建立引用对方的集合导航属性即可

注意:EF2.0中不支持多对多的默认约定,只可以采用中间实体的方式折中表达

提示:这样会自动生成中间表,无需手动创建

学生实体:

//学生实体
public class Student
{[Key]public int StudentId { get; set; }public string Name { get; set; }//集合导航属性public IList<Course> Courses { get; set; }
}

课程实体:

//课程实体
public class Course
{[Key]public int CourseId { get; set; }public string CourseName { get; set; }//集合导航属性public IList<Student> Students { get; set; }
}

实例:文章 和 标签

一篇文章 可以有 多个标签

一个标签 可以对应 多篇文章

image

代码:

文章实体:

using System;
using System.Collections.Generic;
using System.Text;
using System.ComponentModel.DataAnnotations;namespace ConsoleApp3.Models
{public class Blog{[Key]public int Id { get; set; }public string Title { get; set; }public string Content { get; set; }public ICollection<TagsAndBlogs> TagsAndBlogs { get; set; }}
}

标签实体:

using System;
using System.Collections.Generic;
using System.Text;namespace ConsoleApp3.Models
{public class Tag{public int Id { get; set; }public string Title { get; set; }public ICollection<TagsAndBlogs> TagsAndBlogs { get; set; }}
}

中间表实体:

using System;
using System.Collections.Generic;
using System.Text;
using System.ComponentModel.DataAnnotations;namespace ConsoleApp3.Models
{public class TagsAndBlogs{public int Id { get; set; }public DateTime AddDateTime { get; set; }//对博客的外键public int BlogId { get; set; }public Blog Blog { get; set; }//对标签的外键public int TagId { get; set; }public Tag Tag { get; set; }}
}

实例:消费者 和 公司

一个公司 对应 多个消费者

一个消费者 对应 多个公司

image

中间表Entity:

注意:还可以将CompanyId和 ConsumerId设置为Key,形成唯一pair

class ConsumerAndCompany
{[Key]public int ConsumerAndCompanyId { get; set; }[Required]public int CompanyId { get; set; }public virtual Company Company { get; set; }[Required]public int ConsumerId { get; set; }public virtual Consumer Consumer { get; set; }//建立客户关系的时间public DateTime ConnectionDateTime { get; set; }//建立客户关系的备注public String Note { get; set; }
}

Consumer Entity:

class Consumer
{[Key]public int ConsumerId { get; set; }public string ConsumerName { get; set; }public virtual List<ConsumerAndCompany> ConsumerAndCompanys { get; set; } = new List<ConsumerAndCompany>();
}

Company Entity:

class Company
{[Key]public int CompanyId { get; set; }public string CompanyName { get; set; }public virtual List<ConsumerAndCompany> CompanyAndConsumers { get; set; } = new List<ConsumerAndCompany>();
}

设置多对多(Many-to-many relationships)-使用FluentAPI

设置方法1(使用中间表)

折中方式,采用中间实体的形式实现,建立2个实体与中间实体的一对多的约定

多对多在数据库内部通过中间表的方式实现,所以需要添加一个中间Model

本质是:通过中间Model对两端Model的一对多的关系完成的

学生实体

//学生实体
public class Student
{[Key]public int StudentId { get; set; }public string Name { get; set; }//集合导航属性public IList<StudentCourse> StudentCourses { get; set; }
}

课程实体:

//课程实体
public class Course
{[Key]public int CourseId { get; set; }public string CourseName { get; set; }public string Description { get; set; }//集合导航属性public IList<StudentCourse> StudentCourses { get; set; }
}

学生课程关联关系中间实体:

//学生课程关联关系中间实体
public class StudentCourse
{//外键导航属性public int StudentId { get; set; }//导航属性public Student Student { get; set; }//外键导航属性public int CourseId { get; set; }//导航属性public Course Course { get; set; }//添加日期public DateTime AddDateTime { get; set; }
}

建立2个实体到中间实体的一对多的关系:

protected override void OnModelCreating(ModelBuilder modelBuilder)
{//设置StudentCourse实体的主键为StudentId+CourseIdmodelBuilder.Entity<StudentCourse>().HasKey(sc => new { sc.StudentId, sc.CourseId });//建立2个实体到中间实体的一对多的关系modelBuilder.Entity<StudentCourse>().HasOne<Student>(sc => sc.Student).WithMany(s => s.StudentCourses).HasForeignKey(sc => sc.SId);modelBuilder.Entity<StudentCourse>().HasOne<Course>(sc => sc.Course).WithMany(s => s.StudentCourses).HasForeignKey(sc => sc.CId);
}

设置方式2(使用HasMany、WithMany FluentAPI)

提示:这样会自动生成中间表,无需手动创建

学生实体:

//学生实体
public class Student
{[Key]public int StudentId { get; set; }public string Name { get; set; }//集合导航属性public IList<Course> Courses { get; set; }
}

课程实体:

//课程实体
public class Course
{[Key]public int CourseId { get; set; }public string CourseName { get; set; }//集合导航属性public IList<Student> Students { get; set; }
}

在Student实体上配置多对多:

protected override void OnModelCreating(ModelBuilder modelBuilder)
{//建立多对多modelBuilder.Entity<Student>().HasMany(s => s.Courses).WithMany(c => c.Students);
}

也可以在Course实体上配置多对多:

protected override void OnModelCreating(ModelBuilder modelBuilder)
{//建立多对多modelBuilder.Entity<Course>().HasMany(c => c.Students).WithMany(S => S.Courses);
}

实例:一个人有多个公司,一个公司可以属于多个人(多对多)(Fluent API)

Company.cs 公司实体

using Microsoft.EntityFrameworkCore;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.Design;namespace PandaTest
{/// <summary>/// 公司实体/// </summary>public class Company{public Guid Id { get; set; }public string Name { get; set; }public List<Person> Persons { get; set; }}
}

Person.cs 人员实体

using Microsoft.EntityFrameworkCore;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.Design;namespace PandaTest
{/// <summary>/// 人员实体/// </summary>public class Person{public Guid Id { get; set; }public string Name { get; set; }public List<Company> Companies { get; set; }}
}

CompanyEntityConfig.cs 公司实体配置

using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;namespace PandaTest
{/// <summary>/// 公司实体配置/// </summary>public class CompanyEntityConfig : IEntityTypeConfiguration<Company>{public void Configure(EntityTypeBuilder<Company> builder){//配置多对多builder.HasMany(i => i.Persons).WithMany(i => i.Companies);}}
}

PersonEntityConfig.cs 人员实体配置

using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;namespace PandaTest
{/// <summary>/// 人员实体配置/// </summary>public class PersonEntityConfig : IEntityTypeConfiguration<Person>{public void Configure(EntityTypeBuilder<Person> builder){}}
}

TestDbContext.cs 数据库上下文

using Microsoft.EntityFrameworkCore;namespace PandaTest
{/// <summary>/// 数据库上下文/// </summary>public class TestDbContext: DbContext{public TestDbContext(){}protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder){string connectionString = "Server=.;Database=Test;User Id=sa;Password=Password";optionsBuilder.UseSqlServer(connectionString);}protected override void OnModelCreating(ModelBuilder modelBuilder){base.OnModelCreating(modelBuilder);//应用所有实体配置modelBuilder.ApplyConfigurationsFromAssembly(this.GetType().Assembly);}public DbSet<Company> Companies { get; set; }public DbSet<Person> Persons { get; set; }}
}

Program.cs 主程序

using PandaTest;Console.WriteLine("Begin");//创建DbContext
using (TestDbContext db = new TestDbContext())
{//插入数据db.Persons.Add(new Person{Name = "Panda6",Companies = new List<Company>{new Company(){ Name = "公司1"},new Company(){ Name = "公司2"},}});//插入数据db.Companies.Add(new Company{Name = "公司3",Persons = new List<Person>{new Person(){ Name = "Cat"},}});await db.SaveChangesAsync();
}Console.WriteLine("Success");

实例:文章 和 标签

一篇文章 可以有 多个标签

一个标签 可以对应 多篇文章

image

代码:

文章实体:

using System;
using System.Collections.Generic;
using System.Text;
using System.ComponentModel.DataAnnotations;namespace ConsoleApp3.Models
{public class Blog{[Key]public int Id { get; set; }public string Title { get; set; }public string Content { get; set; }public ICollection<TagsAndBlogs> TagsAndBlogs { get; set; }}
}

标签实体:

using System;
using System.Collections.Generic;
using System.Text;namespace ConsoleApp3.Models
{public class Tag{public int Id { get; set; }public string Title { get; set; }public ICollection<TagsAndBlogs> TagsAndBlogs { get; set; }}
}

中间表实体:

using System;
using System.Collections.Generic;
using System.Text;
using System.ComponentModel.DataAnnotations;namespace ConsoleApp3.Models
{public class TagsAndBlogs{public int Id { get; set; }public DateTime AddDateTime { get; set; }//对博客的外键public int BlogId { get; set; }public Blog Blog { get; set; }//对标签的外键public int TagId { get; set; }public Tag Tag { get; set; }}
}

FluentAPI:

protected override void OnModelCreating(ModelBuilder modelBuilder)
{//设置对应到底层数据的数据库的表名modelBuilder.Entity<Blog>().ToTable("Blog");modelBuilder.Entity<Tag>().ToTable("Tag");//设置中间表到标签的一对多关系modelBuilder.Entity<TagsAndBlogs>().ToTable("TagsAndBlogs").HasOne(x => x.Tag).WithMany(x => x.TagsAndBlogs).HasForeignKey(x => x.TagId);//设置中间表到博客的一对多关系modelBuilder.Entity<TagsAndBlogs>().ToTable("TagsAndBlogs").HasOne(x => x.Blog).WithMany(x => x.TagsAndBlogs).HasForeignKey(x => x.BlogId);
}

实例:学生 和 课程

一个学生 可以学习 多门课程

一门课程 可以被 多名学生学习

学生实体:

//学生实体
public class Student
{[Key]public int StudentId { get; set; }public string Name { get; set; }//集合导航属性public IList<StudentCourse> StudentCourses { get; set; }
}

课程实体:

//课程实体
public class Course
{[Key]public int CourseId { get; set; }public string CourseName { get; set; }public string Description { get; set; }//集合导航属性public IList<StudentCourse> StudentCourses { get; set; }
}

学生课程关联关系中间实体:

//学生课程关联关系中间实体
public class StudentCourse
{//外键导航属性public int StudentId { get; set; }//导航属性public Student Student { get; set; }//外键导航属性public int CourseId { get; set; }//导航属性public Course Course { get; set; }//添加日期public DateTime AddDateTime { get; set; }
}

建立2个实体到中间实体的一对多的关系:

protected override void OnModelCreating(ModelBuilder modelBuilder)
{//设置StudentCourse实体的主键为StudentId+CourseIdmodelBuilder.Entity<StudentCourse>().HasKey(sc => new { sc.StudentId, sc.CourseId });//建立2个实体到中间实体的一对多的关系modelBuilder.Entity<StudentCourse>().HasOne<Student>(sc => sc.Student).WithMany(s => s.StudentCourses).HasForeignKey(sc => sc.SId);modelBuilder.Entity<StudentCourse>().HasOne<Course>(sc => sc.Course).WithMany(s => s.StudentCourses).HasForeignKey(sc => sc.CId);
}

其他关联

枚举关联(Enum Mapping)

对于属性的值是枚举值的情况,可以直接使用枚举关联

实例:

//定义需要用到的枚举
public enum Direction
{Up = 0,Down = 1
}public class CarState
{[Key]public int Id {get;set;}//枚举关联public Direction Direction {get;set;}
}

实体继承映射(Entity Inheritance Mapping)

说明

EF5支持2种类型的实体继承映射

一个继承一个表(table-per-hierarchy) 和 一个类型一个表(table-per-type)

默认是一个继承一个表(table-per-hierarchy)

一个继承一个表(table-per-hierarchy)

子类和父类的属性放在集中的一个表中

实例:使用Fluent API定义

//形状实体
public class Shape
{public int Width { get; set; }public int Height { get; set; }
}//立体实体
public class Cube : Shape
{public int Length { get; set; }
}

使用层次结构表意味着,Shape、Cube所有字段会被放在1张数据库表中

不同实体类的字段还可以自定义映射区别字段:

protected override void OnModelCreating(ModelBuilder modelBuilder)
{modelBuilder.Entity<Shape>().HasDiscriminator<string>("ShapeType").HasValue<Shape>("S").HasValue<Cube>("C");
}

最终数据库中的表如下:

Width Height Length ShapeType
"S"
"C"

一个类型一个表(table-per-type)

一个类型对应到底下一个数据库表,继承的属性分开存储到单独的表

实例:使用数据注解定义

[Table("Shape")]
public class Shape
{public int Width { get; set; }public int Height { get; set; }
}[Table("Cube")]
public class Cube : Shape
{public int Length { get; set; }
}

实例:使用Fluent API定义

public class Shape
{public int Width { get; set; }public int Height { get; set; }
}public class Cube : Shape
{public int Length { get; set; }
}protected override void OnModelCreating(ModelBuilder modelBuilder)
{modelBuilder.Entity<Shape>().ToTable("Shape");modelBuilder.Entity<Cube>().ToTable("Cube");
}

EF模型间关联(Modeling Relationships)

https://docs.microsoft.com/en-us/ef/core/modeling/relationships

设置一对一(One-to-one relationships)

设置一对多(One-to-many relationships)

实体对象的关系图如下:

image

注意:其中Product表的Category字段是外键,关联Category表的Id字段

EF代码结构:

Product.cs中除了正常声明字段外,还要用以下代码声明关联关系:

public virtual Category Category1 { get; set; }

Product.cs完整代码:

[Table("Product")]
public partial class Product
{public int Id { get; set; }[Required][StringLength(100)]public string Name { get; set; }public int CategoryId { get; set; }public virtual Category Category { get; set; }
}

Category.cs中需要使用以下代码表示有外键关联到自身

public virtual ICollection<Product> Product { get; set; }

Category.cs完整代码:

public partial class Category
{[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")]public Category(){Product = new HashSet<Product>();}public int Id { get; set; }[Required][StringLength(100)]public string NAME { get; set; }[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]public virtual ICollection<Product> Product { get; set; }
}

设置多对多(Many-to-many relationships)

多对多需要使用中间表方式实现,实体关系图如下:

image

Product表示产品、Order表示订单、OrderDetail表示订单详细的产品内容信息

Product.cs中有一个字段被其他表引用,所以需要声明

public partial class Product
{[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")]public Product(){OrderDetail = new HashSet<OrderDetail>();}public int ProductId { get; set; }[Required][StringLength(200)]public string ProductName { get; set; }[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]public virtual ICollection<OrderDetail> OrderDetail { get; set; }
}

Order.cs中有一个字段被其他表引用,所以需要在类中声明关联关系

public partial class Order
{[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")]public Order(){OrderDetail = new HashSet<OrderDetail>();}public int OrderId { get; set; }public DateTime OrderCreateDateTime { get; set; }[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]public virtual ICollection<OrderDetail> OrderDetail { get; set; }
}

OrderDetail.cs中有2个字段是外键,所以需要在类中声明关联信息

[Table("OrderDetail")]
public partial class OrderDetail
{public int OrderDetailId { get; set; }public int OrderId { get; set; }public int ProductId { get; set; }public virtual Order Order { get; set; }public virtual Product Product { get; set; }
}

SQL Server数据类型 与 .NET数据类型对应关系

image

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.luyixian.cn/news_show_24647.aspx

如若内容造成侵权/违法违规/事实不符,请联系dt猫网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Spring源码分析(八)依赖注入源码解析1:autowire自动注入 和 @Autowired注入

Spring中到底有几种依赖注入的方式&#xff1f; 首先分两种&#xff1a; 手动注入自动注入 手动注入 在XML中定义Bean时&#xff0c;就是手动注入&#xff0c;因为是程序员手动给某个属性指定了值。 <bean name"userService" class"com.luban.service.U…

谷粒商城项目学-分布式基础

项目框架图 分布式基础概念 • 微服务、注册中心、配置中心、远程调用、Feign、网关 • 2、基础开发 • SpringBoot2.0、SpringCloud、Mybatis-Plus、Vue组件化、阿里云对象存储 • 3、环境 • Vagrant、Linux、Docker、MySQL、Redis、逆向工程&人人开源 • 4、开发规范 •…

【LeetCode48:旋转图像(附Java代码)】

旋转图像一、题目描述1.题目内容2.样例二、解决方案1.算法流程1&#xff09;分析2&#xff09;算法流程2.Java代码1&#xff09;核心代码2&#xff09;完整测试代码一、题目描述 1.题目内容 给定一个 n n 的二维矩阵 matrix 表示一个图像。请你将图像顺时针旋转 90 度。 你必…

metamask api 请求 一般操作

参考文档&#xff1a;https://docs.metamask.io/guide/ 注意 metamask 必须是运行在站点之下的 web 页进行操作。 一、检查 metamask 是否安装 metamask 提供了 window.ethereum 供开发者对 metamask&#xff08;以太坊网络&#xff09; 进行交互&#xff0c;当然是需要你已…

DO、VO、BO、DTO、POJO

DO:Domain Object 即数据库表字段 在Java中一一对应关系(有人称它实体类) BO:Business Object 即业务对象,Service层向上传传输的对象。是多个DO的组合形式 VO:view oject 展示层对象,通过接口向前端输出展示的对象 DTO:Date Transfer Object 数据传输对象,controll…

《Linux下软件的管理》

【一】Linux软件包yum 什么是软件包&#xff1f; 在Linux下安装软件&#xff0c;一个通常的办法就是下载程序的源代码&#xff0c;并经行编译&#xff0c;既可得到可执行程序&#xff0c;但是这种办法属实是太麻烦了&#xff0c;因为下载要时间&#xff0c;编译要时间&#x…

根文件系统简介

根文件系统 根文件系统一般也叫做rootfs&#xff0c;那么什么叫根文件系统&#xff1f;看到“文件系统”这四个字&#xff0c;很多人&#xff0c;第一反应就是FATFS、FAT、EXT4、YAFFS和NTFS等这样的文件系统。在这里&#xff0c;根文件系统并不是FATFS这样的文件系统代码&…

SpringCloudAlibaba 通过Dubbo实现微服务之间的RPC调用

目录 一、创建模块化项目 二、公共api接口模块 三、服务提供者 四、服务调用者 五、测试 六、案例代码 在微服务架构中&#xff0c;微服务之间的调用一般我们有两种比较好的解决策略&#xff0c;分别是通过OpenFeign的基于http协议的传输的调用和基于RCP协议的Dubbo框架来…

基于SSM的餐饮管理系统的设计与实现

目 录 前 言 1 第1章 概述 2 1.1 选题背景及意义 2 1.2 技术概述 2 1.2.1 JSP技术概述 2 1.2.2 SpringSprngMVC介绍 3 1.2.3 MySQL数据库概述 3 1.2.4 Mybatis介绍 3 1.2.5 Maven介绍 3 1.3 开发平台介绍 4 1.3.1 Tomcat服务器 4 1.3.2 Eclipse简介 4 第2章 可行性研究 5 2.1 技…

Redis学习和笔记

Redis学习 作为一个程序员&#xff0c;你没有办法不学Redis redis是一个NoSql的&#xff08;远程字典服务的&#xff0c;key_value的数据库&#xff09; redis 能干嘛 内存存储&#xff0c;持久化&#xff0c;内存中是断电就失去&#xff0c;所有说持久化很重要效率高&#…

Linux Command mount 挂载

Linux Command mount 挂载 tags: 文件管理 文章目录Linux Command mount 挂载1. 简介2. 语法3. 退出状态4. 命令选项5. mount 挂载5.1 列出挂载的文件系统5.2 列出特定文件系统5.3 挂载文件系统5.4 使用 /etc/fstab 挂载文件系统5.5 挂载 USB 驱动器5.6 安装 CD-ROM5.7 挂载 I…

电路方案分析(十二)USB Type-C PD 移动电源参考设计方案

USB Type-C PD 移动电源参考设计方案 tips&#xff1a;TI设计方案参考分析&#xff1a;TI Designs&#xff1a;TIDA-01627 1.系统描述 2.系统概述 3.系统供电方案 4.测试数据 5.设计文件 6.关键术语 说明 此移动电源参考设计提供高度集成的 USB Type-C™电力传输 (PD) 解决…

Docter安装

上传安装包 docker-ce-18.06.0.ce-3.el7.x86_64.rpm 安装 yum install docker-ce-18.06.0.ce-3.el7.x86_64.rpm -y 启动docter systemctl start docker systemctl stop docker systemctl restart docker systemctl status docker&#xff08;查看状态&#xff09; 查看doct…

浮点型在内存中的存储

目录 1、浮点数的存储方式 (1) 转化为二进制 (2) 转化为国际标准形式 (3) 使用国际标准形式存储 (4) 存储方式验证 2、从内存中取出浮点数需满足的规则 (1) E 不全为0 或 不全为1 (2) E 全为 0 (3) E 全为 1 浮点数在内存中存储的方式和整型不一样。所以我们在存储的…

2022/10语音识别大作业:基于HMM(隐马尔可夫模型)的Matlab孤立数字语音识别

别看了你要找的就在这。csdn上所有这方面的资源都是收费的&#xff0c;而且没有直接能用的好的&#xff0c;我的也是基于重金买来的两份结合起来做了三天的大修之后才能运行。所以这也不是一份免费分享。但是本文解决了其他资源没有解决的问题&#xff0c;所以50是一个公道的价…

C++——程序员的逼格神器-github

github的重要性&#xff1a; 网络时代的程序员必备。 github的作用&#xff1a; 版本管理多人协作开源共享 常用方案&#xff1a; gitTortoiseGitgithub [Tortoise&#xff0c;程序员常称其为小乌龟&#xff0c;小海龟] 安装配置步骤 1.注册 GitHub: Where the world bui…

JVM之对象的内存模型、创建过程、对象引用、生命周期

JVM之对象的内存模型、创建过程、对象引用、生命周期Java对象内存模型对象头实例数据对齐填充部分对象的创建类加载检查分配内存初始化零值设置对象头执行init方法引用计数法对象的引用强引用软引用弱引用虚引用对象的生命周期创建阶段(Created)应用阶段(In Use)不可见阶段(Inv…

代理ARP (路由式代理ARP+vlan内代理ARP+vlan间代理ARP) [理论+实验验证]

衷心感谢三位大佬的博客 ! ! ! ! 这篇博客主要是为了记录笔记方便查看而整理&#xff0c; 主要内容整理来源&#xff1a; (58条消息) 代理ARP实验_在下小黄的博客-CSDN博客_arp代理实验 (58条消息) 代理ARP_士别三日wyx的博客-CSDN博客_arp代理 (59条消息) 华为ARP代理的三种方…

字节在职三年,如何想要三个月内将软件测试学好,我建议你这样学

目录 13年本科毕业&#xff0c;目前已经工作将近7年时间&#xff0c;第一段工作是在字节工作3年时间&#xff0c;目前是再另外一家大厂工作。今天跟大家分享一下我工作的心得&#xff0c;希望对你有所帮助 我对软件测试的理解 软件测试是软件开发的最后一道防线&#xff0c;…

【Vue 快速入门系列】样式绑定与条件渲染

文章目录前言样式绑定条件渲染前言 在vue中好像一切数据都是可以动态的&#xff0c;那么我们应如何让dom元素中的样式动起来呢&#xff1f;我们既然可以改变dom元素的样式&#xff0c;我们能不能将其隐藏起来呢&#xff1f;今天将会介绍到Vue中如何将属性与dom元素的样式进行绑…