Lerning Entity Framework 6 ------ Defining Relationships


There are three types of relationships in database. They are:

  • One-to-Many
  • One-to-One
  • Many-to-Many

The One-to-Many relationship

Write some codes first:

class Company
{
    public int CompanyId { get; set; }

    [MaxLength(50)]
    public string CompanyName { get; set; }

    public virtual ICollection<Employee> Employees { get; set; }
}

class Employee
{
    public int EmployeeId { get; set; }

    [MaxLength(50)]
    public string EmployeeName { get; set; }

    public virtual int CompanyId { get; set; }
}

class MyContext:DbContext
{
    public MyContext():base("name=Test")
    {

    }
    public DbSet<Company> Companies { get; set; }

    public DbSet<Employee> Employees { get; set; }
}

We use the virtual keyword when define the navigation property. This keyword can enable us to use lazy loading. It' means Entity Framework will load the data to Employees property of Company automatic only when we attempt to access it.

After execute command Update-Database in Nuget command line, take a look at database:

图片.png-4.2kB

The column Companyid is created as the foreign key automatic.

Let's have a test:

static void Main(string[] args)
{
    Company company1 = new Company
    {
        CompanyName = "Baidu",
        Employees = new List<Employee>()
        {
            new Employee
            {
                EmployeeName = "Joey",
            },

            new Employee
            {
                EmployeeName = "Ross",
            }
        }
    };

    AddCompany(company1);
}

private static void AddCompany(Company company)
{
    using (MyContext db = new MyContext())
    {
        db.Companies.Add(company);
        db.SaveChanges();
    }
}

After Run the program, there have been some data:

图片.png-1.3kB

图片.png-1.8kB

Now, Let's try to delete the company:

static void Main(string[] args)
{
    DeleteCompany(1);
}

private static void DeleteCompany(int companyId)
{
    using (MyContext db = new MyContext())
    {
        Company company = db.Companies.Find(companyId);
        if (company != null)
        {
            db.Companies.Remove(company);
            db.SaveChanges();
        }
    }
}

After run the program, you'll find the employee data is deleted also. Cascade deletion is the default way. if you don't want Cascade deletion, you can configurate it by The DbModelBuilder API or Configuration Classes:

class CompanyMap : EntityTypeConfiguration<Company>
{
    public CompanyMap()
    {
        HasMany(c => c.Employees)
            .WithRequired()
            .HasForeignKey(c=>c.CompanyId)
            .WillCascadeOnDelete(false);
    }
}

If you don't need to access proerty CompanyId in class Employee, you'd better remove it from the class Employee. Then Entity Framework will create a foreign key named Company_CompanyId automatic. Of cause, you can define it flexible by using The DbModelBuilder API or Configuration Classes.

The Many-to-Many relationship

Write some codes first:

class Company
{
    public int CompanyId { get; set; }

    [MaxLength(50)]
    public string CompanyName { get; set; }

    public virtual ICollection<Person> Employees { get; set; }
}

class Person
{
    public int PersonId { get; set; }

    [MaxLength(50)]
    public string PersonName { get; set; }

    public virtual ICollection<Company> companies { get; set; }
}

class MyContext:DbContext
{
    public MyContext():base("name=Test")
    {
       
    }

    public DbSet<Company> Companies { get; set; }

    public DbSet<Person> People { get; set; }
}

After execute the command Upate-Database, take a look at the database:

图片.png-2.8kB

Entity Framework has created a junction table named personcompanies. it's contains two columns: personId and companyId.

Of cause, you also can define the columns's name by coding, for example:

class PersonMap:EntityTypeConfiguration<Person>
{
    public PersonMap()
    {
        HasMany(p => p.companies)
            .WithMany(c => c.Employees)
            .Map(m =>
            {
                m.MapLeftKey("PersonId");
                m.MapRightKey("CompanyId");
            });
    }
}

Add it to Configurations of modelBuilder:

// OnModelCreating is a fucntion of DbContext
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
    base.OnModelCreating(modelBuilder);
    modelBuilder.Configurations.Add(new PersonMap());
}

The One-to-One relationship

Coding first:

class Person
{
    public int PersonId { get; set; }

    [MaxLength(50)]
    public string PersonName { get; set; }

    public virtual ICollection<Company> companies { get; set; }

    public virtual Student Student{ get; set; }

}

class Student
{
    [Key]
    public int PersonId { get; set; }

    [MaxLength(200)]
    public string SchoolName { get; set; }

    public virtual Person Person { get; set; }
}

class StudentMap:EntityTypeConfiguration<Student>
{
    public StudentMap()
    {
        HasRequired(s => s.Person)
            .WithOptional(s => s.Student);
    }
}

A student must be a person, but a person dosn't must be student, so, the codes like this:

HasRequired(s => s.Person).WithOptional(s => s.Student);

There is another way to create One-to-One relationship. Please see: Lerning Entity Framework 6 ------ Introduction to TPT.

That's all.

转载于:https://www.cnblogs.com/zzy0471/p/6839220.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值