Learning EntityFramework(4)

public class Destination
{
    public int DestinationId {get; set;} //以Id结尾,默认key。否则会报nokey的异常
    public string Name {get; set;}
    public string Country {get;set;}
    public string Description {get; set;}

    public byte[] Photo {get; set;}

    public List<Lodging> Lodgings {get; set;}
}

public class Lodging
{
    public int LodgingId { get; set; }
    public string Name { get; set; }
    public string Owner { get; set; }
    public bool IsResort { get; set; }
    public Destination Destination { get; set; }
}

一个目的地(Destination)包含了一组借宿(Lodging);而一个借宿(Lodging)属于某个目的地(Destination)。这是上面的Domain Model所展现的。
当一个继承自DbContext(推荐使用DbContext,比ObjectContext更轻量级)实现如下:

public class BreakAwayContext : DbContext
{
    public DbSet<Destination> Destinations { get; set; }
    public DbSet<Lodging> Lodgings { get; set; }
}

当有一个BreakAwayContext的实例被使用时,如果没有存在对应的数据库,会创建数据库和根据类型推测出数据库表结构;
DbContext还包含了Validation的功能

观察数据库中生成的表结构,会发现:

  • Destinations表中,DestinationId是主键。而Lodgings表中有名为Destination_DestinationId的外键,指向DestionationId。
  • 仔细看会发现Destination_DestinationId是可空的
  • 字段类型都为默认长度 e.g. string -> nvarchar(max)
  • Photo字段的类型为varbinary(max)
  • 有一个表叫做dbo.EdmMetadata???not sure it is right?? 包含来一个快照

所以,通过默认的方式,将有很多不好的地方。有两种方式改变:Attribute-based Data Annotations or strongly typed Fluent API.

Attribute-based Data Annotation:

public class Destination
{
    public int DestinationId { get; set; }
    [Required]
    public string Name { get; set; }
    public string Country { get; set; }
    [MaxLength(500)]
    public string Description { get; set; }
    [Column(TypeName="image")]
    public byte[] Photo { get; set; }
    public List<Lodging> Lodgings { get; set; }
}

根据上面的改动,Name在数据库中变成必须的,Description最大长度为500,而Photo的类型为image。
当改动完成后,程序运行不了了。因为跟第一次运行程序有一个区别,数据库已经存在了。:(

首先为什么会报错。当第一次运行一个Model时,这个Model会通过Building Process。然后用它与内存中最新的Model(in-memory model last version-which it can see by reading the EdmMetadata table。EdmMetadata里面包含了一个快照)进行比较。在我们遇到这种情况下,Code First意识到新Model跟之前的Metadata不匹配,不能保证Model能否正确的Mapping,所以,报错来。

然后我们如何处理:

  1. 可以删掉已有的数据库,重新让Code First根据它自己的规则重新创建。
  2. 通过设置策略,告诉应用删除数据库当Model改变:Database.SetInitializer(new DropCreateDatabaseIfModelChanges<T>());

Fluent API:

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
    modelBuilder.Entity<Destination>()
        .Property(d => d.Name).IsRequired();
    modelBuilder.Entity<Destination>()
        .Property(d => d.Description).HasMaxLength(500);
    modelBuilder.Entity<Destination>()
        .Property(d => d.Photo).HasColumnType("image");
    modelBuilder.Entity<Lodging>()
        .Property(l => l.Name).IsRequired().HasMaxLength(200);
}

如果有很多配置,也可以把他们放在一起。通过继承EntityTypeConfigration<T>

public class DestinationConfiguration :
    EntityTypeConfiguration<Destination>
{
    public DestinationConfiguration()
    {
        Property(d => d.Name).IsRequired();
        Property(d => d.Description).HasMaxLength(500);
        Property(d => d.Photo).HasColumnType("image");
    }
}
public class LodgingConfiguration :
    EntityTypeConfiguration<Lodging>
{
    public LodgingConfiguration()
    {
        Property(l => l.Name).IsRequired().HasMaxLength(200);
    }
}

但别忘记在OnModelCreating方法里面加下面代码:
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Configurations.Add(new DestinationConfiguration());
modelBuilder.Configurations.Add(new LodgingConfiguration());
}

Note:

  • DataAnnotation是.NET4用来做验证用的,并不是EF独有的。MVC也可以用Annotation来做前端验证。
  • DataAnnotation和Fluent API各有独特的一些地方。通常来讲,Fluent API比DataAnnotation拥有更多的配置。

What Is a Fluent API?

The concept of a fluent API isn’t specific to Code First or the Entity Framework. The
fundamental idea behind a fluent API involves using chained method calls to produce
code that is easy for the developer to read. The return type of each call then defines the
valid methods for the next call. For example, in the Code First Fluent API, you can use
the Entity method to select an entity to configure. IntelliSense will then show you all
the methods that can be used to configure an Entity. If you then use the Property
method to select a property to configure, you will see all the methods available for
configuring that particular property.

时间: 2024-11-09 02:23:09

Learning EntityFramework(4)的相关文章

Learning EntityFramework(3)

Code First New Database 创建表类型和里面的列 int类型默认为主键类型?? 有两种类型的属性,Navigation属性(定义了对象间的关系)和Scalar属性 使用virtual关键词的属性将被延迟加载,通常被使用在Navigation属性上. 添加EntityFramework的引用 添加以DbContext类为基类的Context类,这个Context类型可以被看作为一个数据库的会话.并在Context类中定义每个对象类型的DbSet<T>属性,用来查询对应类型的实

Learning EntityFramework(5)

复合类型(Complex types) 复合类型(Complex Types)跟Entity类型的区别在于,复合类型(Complex Types)没有Key.复合类型跟踪改变和存储是要依赖宿主类型的. 从代码来看就更直观. 首先,假设我们有一个Person类,这个类包含了SSN,FirstName,LastName和Address的信息.代码如下 public class Person { public int PersonId { get; set; } public int SocialSe

【机器学习实战】Machine Learning in Action 代码 视频 项目案例

MachineLearning 欢迎任何人参与和完善:一个人可以走的很快,但是一群人却可以走的更远 Machine Learning in Action (机器学习实战) | ApacheCN(apache中文网) 视频每周更新:如果你觉得有价值,请帮忙点 Star[后续组织学习活动:sklearn + tensorflow] ApacheCN - 学习机器学习群[629470233] 第一部分 分类 1.) 机器学习基础 2.) k-近邻算法 3.) 决策树 4.) 基于概率论的分类方法:朴素

Neural Networks and Deep Learning学习笔记ch1 - 神经网络

近期開始看一些深度学习的资料.想学习一下深度学习的基础知识.找到了一个比較好的tutorial,Neural Networks and Deep Learning,认真看完了之后觉得收获还是非常多的.从最主要的感知机開始讲起.到后来使用logistic函数作为激活函数的sigmoid neuron,和非常多其它如今深度学习中常使用的trick. 把深度学习的一个发展过程讲得非常清楚,并且还有非常多源代码和实验帮助理解.看完了整个tutorial后打算再又一次梳理一遍,来写点总结.以后再看其它资料

Deep Learning Enables You to Hide Screen when Your Boss is Approaching

https://github.com/Hironsan/BossSensor/ 背景介绍 学生时代,老师站在窗外的阴影挥之不去.大家在玩手机,看漫画,看小说的时候,总是会找同桌帮忙看着班主任有没有来. 一转眼,曾经的翩翩少年毕业了,新的烦恼来了,在你刷知乎,看视频,玩手机的时候,老板来了! 不用担心,不用着急,基于最新的人脸识别+手机推送做出的BossComing.老板站起来的时候,BossComing会通过人脸识别发现老板已经站起来,然后通过手机推送发送通知“BossComing”,并且震动告

Machine Learning In Action 第二章学习笔记: kNN算法

本文主要记录<Machine Learning In Action>中第二章的内容.书中以两个具体实例来介绍kNN(k nearest neighbors),分别是: 约会对象预测 手写数字识别 通过“约会对象”功能,基本能够了解到kNN算法的工作原理.“手写数字识别”与“约会对象预测”使用完全一样的算法代码,仅仅是数据集有变化. 约会对象预测 1 约会对象预测功能需求 主人公“张三”喜欢结交新朋友.“系统A”上面注册了很多类似于“张三”的用户,大家都想结交心朋友.“张三”最开始通过自己筛选的

repost: Deep Reinforcement Learning

From: http://wanghaitao8118.blog.163.com/blog/static/13986977220153811210319/ accessed 2016-03-10 深度强化学习(Deep Reinforcement Learning)的资源 Google的Deep Mind团队2013年在NIPS上发表了一篇牛x闪闪的文章,亮瞎了好多人眼睛,不幸的是我也在其中.前一段时间收集了好多关于这方面的资料,一直躺在收藏夹中,目前正在做一些相关的工作(希望有小伙伴一起交流)

Spark MLlib Deep Learning Convolution Neural Network (深度学习-卷积神经网络)3.1

3.Spark MLlib Deep Learning Convolution Neural Network (深度学习-卷积神经网络)3.1 http://blog.csdn.net/sunbow0 Spark MLlib Deep Learning工具箱,是根据现有深度学习教程<UFLDL教程>中的算法,在SparkMLlib中的实现.具体Spark MLlib Deep Learning(深度学习)目录结构: 第一章Neural Net(NN) 1.源码 2.源码解析 3.实例 第二章D

Spark MLlib Deep Learning Convolution Neural Network (深度学习-卷积神经网络)3.2

3.Spark MLlib Deep Learning Convolution Neural Network(深度学习-卷积神经网络)3.2 http://blog.csdn.net/sunbow0 第三章Convolution Neural Network (卷积神经网络) 2基础及源码解析 2.1 Convolution Neural Network卷积神经网络基础知识 1)基础知识: 自行google,百度,基础方面的非常多,随便看看就可以,只是很多没有把细节说得清楚和明白: 能把细节说清