这篇文章将讨论复杂类型。

默认情况下,EF4.1 将类映射到表,这是约定,但是有时候,我们需要模型比表的粒度更细一些。

地址是一个典型的例子,看一下下面的客户类。


publicclass Client
{
publicint ClientID { get; set; }
[Required]
[StringLength(, MinimumLength=)]
publicstring ClientName { get; set; }
public Address ResidentialAddress { get; set; }
public Address DeliveryAddress { get; set; }
} publicclass Address
{
[Required]
publicint StreetNumber { get; set; }
[Required]
[StringLength(, MinimumLength=)]
publicstring StreetName { get; set; }
}

我们不希望其中的两个地址属性都映射到地址表中的记录,而是让 EF4.1 都映射到一张表中,将地址展开,如何做到呢?可以通过复杂类型。

像我们前面看到的,我们总是通过标签或者模型构建器来覆盖默认约定。我提到过,当我们丰富业务模型的时候,例如必填项,我建议使用属性。现在我考虑将类中的复杂属性映射到表中的字段,所以这里不是用标签,而是使用模型构建器。


protectedoverridevoid OnModelCreating(DbModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder); modelBuilder.Entity<Client>().Property(x => x.ClientID)
.HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
modelBuilder.ComplexType<Address>();
modelBuilder.Entity<Client>().Property(i => i.ResidentialAddress.StreetNumber).HasColumnName("ResStreetNumber");
modelBuilder.Entity<Client>().Property(i => i.ResidentialAddress.StreetName).HasColumnName("ResStreetName");
modelBuilder.Entity<Client>().Property(i => i.DeliveryAddress.StreetNumber).HasColumnName("DelStreetNumber");
modelBuilder.Entity<Client>().Property(i => i.DeliveryAddress.StreetName).HasColumnName("DelStreetName"); }

首先,我指定 client-id 作为自动增长的标识列。然后,指定 Address 是复杂类型。如果愿意的话,也可以将 [ComplexType] 标签加到类上来说明。然后,使用 Lambda 表达式将每一个子属性映射到列上,这将会生成如下的表。

现在,可以使用模型了。


using (var context1 =new MyDomainContext())
{
var client =new Client
{
ClientName ="Joe",
ResidentialAddress =new Address
{
StreetNumber =,
StreetName ="Oxford"
},
DeliveryAddress =new Address
{
StreetNumber =,
StreetName ="Nolif"
}
};
context1.Clients.Add(client); context1.SaveChanges();
}
using (var context2 =new MyDomainContext())
{
var clients = from w in context2.Clients
where w.ClientName =="Joe"
select w; foreach (var client in clients)
{
Console.WriteLine("client residential StreetNumber: "+ client.ResidentialAddress.StreetNumber);
Console.WriteLine("client residential StreetName: "+ client.ResidentialAddress.StreetName);
Console.WriteLine("client delivery StreetNumber: "+ client.DeliveryAddress.StreetNumber);
Console.WriteLine("client delivery StreetName: "+ client.DeliveryAddress.StreetName);
}
}

对于复杂类型,最值得注意的是空的管理。即使复杂类型的所有属性都是可空的,你也不能将整个复杂类型的对象设为 null, 例如,在这种情况下,即使街道的名称和街道的号码不是必填的,也不能有一个住宅的地址为 null,需要创建一个所有属性都是 null 的地址对象来表示。同样的道理,当你获取一个实体的时候,即使所有的属性都是 null ,EF4.1 也将会创建一个复杂类型的对象。

Entity Framework 4.1:复杂类型的更多相关文章

  1. Entity Framework 教程——Entity Framework中的实体类型

    Entity Framework中的实体类型 : 在之前的章节中我们介绍过从已有的数据库中创建EDM,它包含数据库中每个表所对应的实体.在EF 5.0/6.0中,存在POCO 实体和动态代理实体两种. ...

  2. 解决 Entity Framework 6.0 decimal 类型精度问题

    Ø  前言 本文主要解决 EF 中对于 MSSQL 数据库的 decimal 类型经度问题,经实验该问题仅在 CodeFirst 模式的情况下发生,话不多说直接看代码. 1.   假设我们有一张 Cu ...

  3. asp.net core + entity framework core 多数据库类型支持实战

    根据微软官方文档的说法,有两种方法可以实现在一个app中同时适应多种不同类型的数据库,并且全部支持migrations操作.其一,使用两个dbcontext:其二,修改migration文件,添加特定 ...

  4. ASP.NET MVC with Entity Framework and CSS一书翻译系列文章之第二章:利用模型类创建视图、控制器和数据库

    在这一章中,我们将直接进入项目,并且为产品和分类添加一些基本的模型类.我们将在Entity Framework的代码优先模式下,利用这些模型类创建一个数据库.我们还将学习如何在代码中创建数据库上下文类 ...

  5. Entity Framework 程序设计入门二 对数据进行CRUD操作和查询

    前一篇文章介绍了应用LLBL Gen生成Entity Framework所需要的类型定义,用一行代码完成数据资料的读取, <LLBL Gen + Entity Framework 程序设计入门& ...

  6. [转]Entity Framework vs. LINQ to SQL

    Entity Framework和LINQ to SQL到底有什么区别?这是一个很常见的问题.下面的表中简要罗列了两种技术的主要区别. LINQ to SQL Entity Framework 复杂度 ...

  7. Entity Framework 插入数据 解决主键非自增问题

    http://blog.csdn.net/educast/article/details/8632806 与Entity Framework相伴的日子痛并快乐着.今天和大家分享一下一个快乐,两个痛苦. ...

  8. LINQ to SQL和Entity Framework对比与关联 (转载)

    LINQ to SQL和Entity Framework对比与关联       LINQ to SQL和Entity Framework都是一种包含LINQ功能的对象关系映射技术.他们之间的本质区别在 ...

  9. LINQ to SQL和Entity Framework对照

    LINQ to SQL和Entity Framework都是一种包括LINQ功能的对象关系映射技术.他们之间的本质差别在于EF对数据库架构和我们查询的类型实行了更好的解耦. 使用EF,我们查询的对象不 ...

  10. Entity Framework技巧系列之三 - Tip 9 – 12

    提示9. 怎样直接删除一个对象而无需检索它 问题 最常见的删除Entity Framework中实体的方式是将你要删除的实体传入Context中并像如下这样删除: 1 // 按ID查找一个类别 2 / ...

随机推荐

  1. django模型manager学习记录

    Managers 在语句Book.objects.all()中,objects是一个特殊的属性,需要通过它查询数据库. 在第5章,我们只是简要地说这是模块的manager .现在是时候深入了解mana ...

  2. IntelliJ IDEA 取消控制台行数限制

    在idea7之后的版本中取消了 控制台行数设置 选项,只能通过更改配置文件进行更改 在%安装目录%/bin中找到idea.properties文件,更改idea.cycle.buffer.size项值 ...

  3. 2017.7.14 使用case when和group by将多条数据合并成一行,并且根据某些列的合并值做条件判断来生成最终值

    参考来自:http://bbs.csdn.net/topics/390737006 1.效果演示 (1)不做处理 (2)合并多列,并对后四列的值做并集处理 2.SQL语句 (1)不做处理 SELECT ...

  4. CTAssetsPickerController 选中图片不显示对号的问题解决

    转载自:http://blog.csdn.net/qq_27304667/article/details/53218547 早上AppStore审核通过,下载来看看.突然发现一个选择图片时候选中的标识 ...

  5. Linux——Django 开发环境部署(一)

    Django 开发环境部署(一) 之所以 写这篇文章的原因在于django环境的确轻松搭建,之前Ubuntu上安装了,的确很轻松,但是后期我才知道随便做个环境出来很容易到了后面很麻烦,污 染了系统里的 ...

  6. linux查找并杀死进程shell

    ps -ef|grep java\ -cp\ .*jar|grep -v grep|cut -c 9-15|xargs kill -9

  7. react-native + teaset 实现 Tabbar

    1.代码 src/pages/MainPage/index.js /** * 主页面 */ import React, {Component} from 'react'; import { BackH ...

  8. 【Java】Java_20 Scanner获取键盘输入

    使用Scanner类可以很方便的获取用户的键盘输入,Scanner是一个基于正则表达式子的文本扫描器,他可以从文件.输入流.字符串中解析出基本类型值和字符串值. 例子示意: package com.o ...

  9. Android插件化开发,初入殿堂

    好久没有写博客了,这次准备写写我这几天的研究成果--Android插件化开发框架CJFrameForAndroid. 好久没有写博客了,这次准备写写我这几天的研究成果--Android插件化开发框架C ...

  10. 转:HTTP协议--- multipart/form-data请求分析

    转自:http://blog.csdn.net/five3/article/details/7181521 首先来了解什么是multipart/form-data请求: 根据http/1.1 rfc ...