Configure One-to-Zero-or-One Relationship:

Here, we will configure One-to-Zero-or-One relationship between two entities, e.g. Entity1 can be associated with zero or only one instance of Entity2.

Take an example of the following Student and StudentAddress entities.

public class Student
{
public Student() { } public int StudentId { get; set; }
public string StudentName { get; set; } public virtual StudentAddress Address { get; set; } } public class StudentAddress
{
public int StudentAddressId { get; set; } public string Address1 { get; set; }
public string Address2 { get; set; }
public string City { get; set; }
public int Zipcode { get; set; }
public string State { get; set; }
public string Country { get; set; } public virtual Student Student { get; set; }
}

Visit Entity Relationship section to understand how EF manages one-to-one, one-to-many, and many-to-many relationships.

Now, let's configure Student and StudentAddress entities for One-to-Zero-or-One relationship where Student can have zero or maximum one StudentAddress.

As you may know, a one-to-zero-or-one relationship happens when the primary key of one table becomes PK & FK in another table in relational database such as SQL Server. So, we need to configure above entities in such a way that EF creates Students and StudentAddresses table in the DB where it will make StudentId in Student table as PK and StudentAddressId column in StudentAddress table as PK and FK both.

Configure one-to-zero-or-one relationship using DataAnnotations:

Here, we will apply DataAnnotations attributes on Student and StudentAddress entities to establish one-to-zero-or-one relationship.

The Student entity follows the default code-first convention as it includes StudentId property which will be key property. So we don't need to apply any attributes on it because EF will create Students table and make StudentId as a primary key in the DB.

For the StudentAddress entity, we need to configure StudentAddressId as PK & FK both. StudentAddressId property follows the default convention for primary key. So we don't need to apply any attribute for PK. However, we also need to make it a foreign key which points to StudentId. So, apply [ForeignKey("Student")] on StudentAddressId property which will make it foreign key for Student entity as shown below.

public class Student
{
public Student() { } public int StudentId { get; set; }
public string StudentName { get; set; } public virtual StudentAddress Address { get; set; } } public class StudentAddress
{
[ForeignKey("Student")]
public int StudentAddressId { get; set; } public string Address1 { get; set; }
public string Address2 { get; set; }
public string City { get; set; }
public int Zipcode { get; set; }
public string State { get; set; }
public string Country { get; set; } public virtual Student Student { get; set; }
}

Thus, Student and StudentAddress entities has One-to-Zero-or-One relationship.

When StudentAddress entity does not follow conventions:

If, for example, StudentAddress entity does not follow the convention for PK i.e. different name for Id property then you need to configure it for PK as well. Consider the following StudentAddress entity which has property name StudentId instead of StudentAddressId.

public class Student
{
public Student() { } public int StudentId { get; set; }
public string StudentName { get; set; } public virtual StudentAddress Address { get; set; } } public class StudentAddress
{
[Key, ForeignKey("Student")]
public int StudentId { get; set; } public string Address1 { get; set; }
public string Address2 { get; set; }
public string City { get; set; }
public int Zipcode { get; set; }
public string State { get; set; }
public string Country { get; set; } public virtual Student Student { get; set; }
}

In the above example, we need to configure StudentId property as Key as well as ForeignKey. This will make StudentId property in StudentAddress entity as PK and FK both.

Note: Student include StudentAddress navigation property and StudentAddress includes Student navigation property. With one-to-zero-or-one relationship, Student can be saved without StudentAddress but StudentAddress entity cannot be saved without Student entity. EF will throw an exception if you try to save StudentAddress entity without Student entity.

Configure One-to-Zero-or-One relationship using Fluent API:

Here, we will use Fluent API to configure Student and StudentAddress entities. Please note that we will not apply any DataAnnotations attributes in Student and StudentAddress entities because we will use Fluent API to configure them.

When Student and StudentAddress follow the conventions:

Student and StudentAddress entities follow the default code-first convention for PrimaryKey. So, we don't need to configure them to define their PrimaryKeys. We only need to configure StudentAddress entity where StudentAddressId should be ForeignKey.

The following example sets one-to-zero or one relationship between Student and StudentAddress using Fluent API.

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{ // Configure Student & StudentAddress entity
modelBuilder.Entity<Student>()
.HasOptional(s => s.Address) // Mark Address property optional in Student entity
.WithRequired(ad => ad.Student); // mark Student property as required in StudentAddress entity. Cannot save StudentAddress without Student }

In the above example, Student entity is configured using HasOptional() method which indicates that the StudentAddress navigation property in Student entity is an optional (not required when saving Student entity). Then, WithRequired() method configures StudentAddress entity and make Student navigation property of StudentAddress as required (required when saving StudentAddress entity. It will throw an exception when StudentAddress entity is saving without Student navigation property). This will make StudentAddressId as ForeignKey also.

Thus, you can configure One-to-Zero-or-one relationship between two entities where Student entity can be saved without attaching StudentAddress object to it but StudentAddress entity cannot be saved without attaching an object of Student entity. This makes one end required.

When StudentAddress entity do not follow conventions:

Now, let's take an example of StudentAddress entity where it does not follow primary key convention i.e. have different Id property name than <type name>Id. Consider the following Student and StudentAddress entities.

public class Student
{
public Student() { } public int StudentId { get; set; }
public string StudentName { get; set; } public virtual StudentAddress Address { get; set; } } public class StudentAddress
{
public int StudentId { get; set; } public string Address1 { get; set; }
public string Address2 { get; set; }
public string City { get; set; }
public int Zipcode { get; set; }
public string State { get; set; }
public string Country { get; set; } public virtual Student Student { get; set; }
}

So now, we need to configure StudentId property of StudentAddress for PrimaryKey of StudentAddress as well as ForeignKey as shown below.

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
// Configure StudentId as PK for StudentAddress
modelBuilder.Entity<StudentAddress>()
.HasKey(e => e.StudentId); // Configure StudentId as FK for StudentAddress
modelBuilder.Entity<Student>()
.HasOptional(s => s.Address)
.WithRequired(ad => ad.Student); }

Configure One-to-One relationship using Fluent API:

We can configure One-to-One relationship between entities using Fluent API where both ends are required, meaning Student entity object must include StudentAddress entity object and StudentAddress entity must include Student entity object in order to save it.

Note:One-to-one relationship is technically not possible in MS SQL Server. It will always be one-to-zero or one. EF forms One-to-One relationships on entities not in DB.

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
// Configure StudentId as PK for StudentAddress
modelBuilder.Entity<StudentAddress>()
.HasKey(e => e.StudentId); // Configure StudentId as FK for StudentAddress
modelBuilder.Entity<Student>()
.HasRequired(s => s.Address)
.WithRequiredPrincipal(ad => ad.Student); }

In the above example, modelBuilder.Entity<Student>().HasRequired(s => s.Address) makes Address property of StudentAddress is required. .WithRequiredPrincipal(ad => ad.Student) makes Student property of StudentAddress entity as required. Thus it configures both ends required. So now, when you try to save Student entity without address or StudentAddress entity without Student, it will throw an exception.

Note: Here, Principal entity is Student and dependent entity is StudentAddress.

DataAnnotations and Fluent API example for one-to-zero or one relationship will create the following database:

You can check the relationship between Student and StudentAddress in the database, as shown below:

If you create an entity data model of a created database then it will appear like the diagram shown below:

Learn how to configure a one-to-many relationship in the next section.

Entity Framework Code-First(11):Configure One-to-One的更多相关文章

  1. Entity Framework Tutorial Basics(11):Code First

    Code First development with Entity Framework: Entity Framework supports three different development ...

  2. Entity Framework Code first(转载)

    一.Entity Framework Code first(代码优先)使用过程 1.1Entity Framework 代码优先简介 不得不提Entity Framework Code First这个 ...

  3. Entity Framework Code First (三)Data Annotations

    Entity Framework Code First 利用一种被称为约定(Conventions)优于配置(Configuration)的编程模式允许你使用自己的 domain classes 来表 ...

  4. Entity Framework Code First (二)Custom Conventions

    ---------------------------------------------------------------------------------------------------- ...

  5. Entity Framework Code First (一)Conventions

    Entity Framework 简言之就是一个ORM(Object-Relational Mapper)框架. Code First 使得你能够通过C#的类来描述一个模型,模型如何被发现/检测就是通 ...

  6. Entity Framework Code First (七)空间数据类型 Spatial Data Types

    声明:本文针对 EF5+, Visual Studio 2012+ 空间数据类型(Spatial Data Types)是在 EF5 中引入的,空间数据类型表现有两种: Geography (地理学上 ...

  7. Entity Framework Code First (四)Fluent API - 配置属性/类型

    上篇博文说过当我们定义的类不能遵循约定(Conventions)的时候,Code First 提供了两种方式来配置你的类:DataAnnotations 和 Fluent API, 本文将关注 Flu ...

  8. Entity Framework Code First (八)迁移 Migrations

    创建初始模型和数据库 在开始使用迁移(Migrations)之前,我们需要一个 Project 和一个 Code First Model, 对于本文将使用典型的 Blog 和 Post 模型 创建一个 ...

  9. Entity Framework Code First (六)存储过程

    声明:本文只针对 EF6+ 默认情况下,Code First 对实体进行插入.更新.删除操作是直接在表上进行的,从 EF6 开始你可以选择使用存储过程(Stored Procedures) 简单实体映 ...

  10. Entity Framework Code First (五)Fluent API - 配置关系

    上一篇文章我们讲解了如何用 Fluent API 来配置/映射属性和类型,本文将把重点放在其是如何配置关系的. 文中所使用代码如下 public class Student { public int ...

随机推荐

  1. Python问题解决记录

    Python如何进行中文注释:网址 解决Python UnicodeEncodeError: 'ascii' codec can't encode: 网址1.网址2.网址3 Python 字符串转换为 ...

  2. hbase shell-security(安全指令)

    hbase shell安全指令篇: grant list_security_capabilities revoke user_permission 正在编辑中

  3. SQl Server 中登录名 、用户、角色、概念一览

      转载:http://www.2cto.com/database/201306/216922.html       数据库,角色,用户,安全        登录SQL server 2008可以用w ...

  4. Qt 怎么画一个圆角矩形对话框,或者圆角控件

    1. 2. 在自定义控件的 构造函数中加入如下一段断码 this->setWindowFlags(Qt::Dialog | Qt::FramelessWindowHint); //隐藏对话框标题 ...

  5. BZOJ 3391 [Usaco2004 Dec]Tree Cutting网络破坏:dfs【无根树 节点分枝子树大小】

    题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=3391 题意: 给你一棵无根树,求分支size均不大于一半点数的点. 题解: 假定1为根. ...

  6. 学习HTML5

    CSS,层叠样式表,能为网页增添样式的电脑语言. UL属于无序列表 OL属于有序列表 DL属于自定义列表.

  7. vim乱码的解决

    解决vim文件乱码,打开文件乱码,菜单,提示信息乱码: 有四个跟字符编码方式有关的选项,encoding.fileencoding.fileencodings.termencoding 在linux中 ...

  8. elasticsearch的store属性跟_source字段——如果你的文档长度很长,存储了_source,从_source中获取field的代价很大,你可以显式的将某些field的store属性设置为yes,否则设置为no

    转自:http://kangrui.iteye.com/blog/2262860 众所周知_source字段存储的是索引的原始内容,那store属性的设置是为何呢?es为什么要把store的默认取值设 ...

  9. 7 Python 数据类型—列表

    列表(list)是Python以及其他语言中最常用到的数据结构之一.Python使用使用中括号 [ ] 来解析列表 序列是Python中最基本的数据结构.序列中的每个元素都分配一个数字 - 它的位置, ...

  10. centos 静态拨号

    本人系统centos6.5:虚拟机太丑,固ssh. centos的与联网相关的配置文件在 $ /etc/sysconfig/network-scripts DHCP方式-联网 打开文件 $ vim / ...