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:

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:

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:

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.

Lerning Entity Framework 6 ------ Defining Relationships的更多相关文章

  1. Lerning Entity Framework 6 ------ Defining the Database Structure

    There are three ways to define the database structure by Entity Framework API. They are: Attributes ...

  2. Lerning Entity Framework 6 ------ Handling concurrency With SQL Server Database

    The default Way to handle concurrency of Entity Framework is using optimistic concurrency. When two ...

  3. Lerning Entity Framework 6 ------ Working with in-memory data

    Sometimes, you need to find some data in an existing context instead of the database. By befault, En ...

  4. Lerning Entity Framework 6 ------ Inserting, Querying, Updating, and Deleting Data

    Creating Entities First of all, Let's create some entities to have a test. Create a project Add foll ...

  5. Lerning Entity Framework 6 ------ Introduction to TPH

    Sometimes, you have created two models. They have the same parent class like this: public class Pers ...

  6. Lerning Entity Framework 6 ------ Complex types

    Complex types are classes that map to a subset of columns of a table.They don't contains key. They a ...

  7. Lerning Entity Framework 6 ------ Using a commandInterceptor

    Sometimes, We want to check the original sql statements. creating a commandInterceptor is a good way ...

  8. Lerning Entity Framework 6 ------ A demo of using Entity framework with MySql

    Create a new project named MySqlTest Install following packages by right-clicking on the References ...

  9. Lerning Entity Framework 6 ------ Joins and Left outer Joins

    Joins allow developers to combine data from multiple tables into a sigle query. Let's have a look at ...

随机推荐

  1. js 光标位置处理

    /** * 获取选中文字 * 返回selection,toString可拿到结果,selection含有起始光标位置信息等 **/ function getSelectText() { var tex ...

  2. JQuery中after() append() appendTo()的区别

    首先 after() 是追加在元素外边而append() appendTo()是追加在元素里面. $(selector).after(content) $("span").afte ...

  3. Java利用递归实现扫雷

    package 扫雷; import java.math.*; import java.util.Scanner; public class 扫雷 { //记录翻开次数 static int k=0; ...

  4. Java crash问题分析

    Java的应用有时候会因为各种原因Crash,这时候会产生一个类似java_errorpid.log的错误日志.可以拿到了 这个日志,怎样分析Crash的原因呢?下面我们来详细讨论如何分析java_e ...

  5. [RequireComponent(typeof(....))]

    RequireComponent的使用: 当你添加的一个用了RequireComponent组件的脚本,需要的组件将会自动被添加到game object(游戏物体).这个可以有效的避免组装错误.举个例 ...

  6. Java语法基础课 原码 反码 补码

    原码就是符号位加上真值的绝对值, 即用第一位表示符号, 其余位表示值. 反码的表示方法是:正数的反码是其本身:负数的反码是在其原码的基础上, 符号位不变,其余各个位取反. 补码的表示方法是在反码的基础 ...

  7. stacking过程

    图解stacking原理: 上半部分是用一个基础模型进行5折交叉验证,如:用XGBoost作为基础模型Model1,5折交叉验证就是先拿出四折作为training data,另外一折作为testing ...

  8. Python中subprocess 模块 创建并运行一个进程

     python的subprocess模块,看到官方声明里说要尽力避免使用shell=True这个参数,于是测试了一下: from subprocess import call import shlex ...

  9. Firefox,chrome,IE上传图片预览

    首先判断IE或是Firefox,chrome.本文只测试了IE8中和Firefox,chrome是不一样的. 判断是否IE: if(-[1,]){//判断浏览器不是IE    //alert((-[1 ...

  10. 将驼峰转化为下化线(将型如AbcDef转化为abc_def)

    strtolower(preg_replace('/((?<=[a-z])(?=[A-Z]))/', '_', 'AbcDef'))