EFCodeFirst学习笔记

合集下载

EF_Code_First:数据查询

EF_Code_First:数据查询

EF Code First:数据查询EF的CodeFirst是个好东西,让我们完全不用考虑数据库端(注意,这里并不是说不需要对数据库知识进行了解),一切工作都可以通过代码来完成。

EF是ORM,已经把数据访问操作封装得很好了,可以直接在业务层中使用,那我们为什么还要对其进行那么多封装呢?在我看来,封装至少能带来如下的好处。

一、前言首先对大家表示抱歉,这个系列已经将近一个月没有更新了,相信大家等本篇更新都等得快失望了。

实在没办法,由于本人水平有限,写篇博客基本上要大半天的时间,最近实在是抽不出这么长段的空闲时间来写。

另外也是一直没想好本篇应该怎样写比较容易理解,于是就一天一天的拖着了。

废话不多说,言归正传。

EF的CodeFirst是个好东西,让我们完全不用考虑数据库端(注意,这里并不是说不需要对数据库知识进行了解),一切工作都可以通过代码来完成。

EF是ORM,已经把数据访问操作封装得很好了,可以直接在业务层中使用,那我们为什么还要对其进行那么多封装呢?在我看来,封装至少能带来如下的好处:1.把EF的相关对象封装在数据访问层中,解除了业务层对EF的依赖。

2.统一EF的数据操作,以保证业务层使用相同的代码规范3.隐藏EF的敏感配置,降低EF的使用难度这里就引入一个问题,应该怎样来进行EF的封装呢,既要保证使用的统一与方便性,又要保持EF的灵便性,否则,封装将变成给业务层设置障碍。

下面,主要针对数据查询进对可能出现的误用情况进行分析。

二、查询问题分析(一) 数据查询应该在哪做在EF中,面向对象的数据查询主要提供了两种方式:1.TEntity DbSet<TEntity>.Find(params object[] keyValues):针对主键设计的通过主键查找单个实体,会先在EF的本地数据集Local中进行查询,如果没有,再去数据库中查询。

2.IQueryable<T>、IEnumerable<T>类型的所有数据查询的扩展方法(由于DbSet<T>继承于IQueryable<T>与IEnumerable<T>),如SingleOrDefault,FirstOrDefault,Where等。

C#EF使用(CodeFirst模式)

C#EF使用(CodeFirst模式)

C#EF使⽤(CodeFirst模式)⼀、EF的简单介绍,EF是⼀种通过映射操作实现数据交互的ORM框架技术⼆、简单使⽤1、安装EntityFrameWork(通过⼯具-NeGet程序包管理-管理NeGet程序包来安装或者添加引⽤)*最终的⽬的是为了在项⽬上添加进这两个dll注:如果是使⽤了web API,要在API层引⼊这两个dll安装完会在app.config或者web.config⽣成此配置信息2.配置数据库连接字符串,如果⽤了web Api同样要在api层的webconfig中配置连接字符串注:连接字符串可通过在桌⾯建.udl⽂件来获取3.开始写想要⽣成的数据库表对应的模型类(需要添加ponentModel.DataAnnotations这个引⽤,此引⽤可添加模型组件特性的注释如:主键、字符长度、表名字、列名字、以及是否映射到数据库等)--如果是有主外键关系的表则在模型中:(或给它加特性)public int 外键表(实体类)id名字{get;set;}public 外键表(实体类)id名字外键表(实体类)id名字s{get;set;}4.写上下⽂类5.开始初始化数据库(记得把上下⽂类所在的类库设置为启动项或者在程序包控制台的默认项⽬中选择此类库)在程序包管理控制台中输⼊:get-help EntityFrameWork*2.通过命令,开始迁移:Enable-Migrations --命令是申请开始迁移的,Add-Migration --是添加迁移:需要给它取个名字,如: Add-Migration InitUpdate-Database --这个是在数据库⽣成表的语句每次执⾏都会在项⽬中和SQL Server 中⽣成迁移⽂件:接下来就可以使⽤EF语句进⾏操作了。

ef code first 表中文注释

ef code first 表中文注释

ef code first 表中文注释1. 主键(Primary Key):主键是用于唯一标识一条记录的字段或字段组合。

在 EF Code First 中,可以使用 "[Key]" 注释来标识主键。

主键可以是单个字段,也可以是多个字段的组合。

使用主键可以提高数据的查询效率,并且可以保证数据的唯一性。

2. 外键(Foreign Key):外键用于关联两个表之间的关系。

在 EF Code First 中,可以使用 "[ForeignKey]" 注释来标识外键。

外键通常是一个与其他表的主键相关联的字段。

通过使用外键,可以在两个表之间建立关系,并且可以实现数据的引用和一致性。

3. 非空(Not Null):非空用于限制字段的值不能为空。

在 EF Code First 中,可以使用 "[Required]" 注释来标识非空字段。

非空字段可以确保数据的完整性和有效性,避免了数据的丢失和错误。

4. 唯一(Unique):唯一用于限制字段的值不能重复。

在 EF Code First 中,可以使用 "[Index(IsUnique = true)]" 注释来标识唯一字段。

唯一字段可以确保数据的唯一性,避免了重复数据的插入和查询。

5. 长度(Length):长度用于限制字段值的最大长度。

在 EF Code First 中,可以使用 "[MaxLength]" 注释来标识字段的最大长度。

长度可以用于限制字符串字段的长度,避免了数据的溢出和错误。

6. 默认值(Default Value):默认值用于指定字段在插入数据时的默认值。

在 EF Code First 中,可以使用 "[DefaultValue]" 注释来标识字段的默认值。

默认值可以用于设置字段的默认数值或默认字符串,避免了数据插入时的繁琐操作。

EF框架step by step(7)—Code First DataAnnotations(1)

EF框架step by step(7)—Code First DataAnnotations(1)

EF框架step by step(7)—Code First DataAnnotations(1)2011-05-12 08:37 by 杨延成, 4204 阅读, 25评论, 收藏, 编辑Data annotation特性是在.NET 3.5中引进的,给 web应用中的类提供了一种添加验证的方式。

Code First允许你使用代码来建立实体框架模型,同时允许用Data annotation特性来配置类和属性的某些特性。

其实在前面的几篇文章中,有用到几个,在这一篇里,进行一次比较全面的介绍KeyEF框架要求每个实体必须有主键字段,他需要根据这个主键字段跟踪实体。

CodeFirst方法在创建实体时,也必须指定主键字段,默认情况下属性被命名为ID、id或者[ClassName]Id,将映射为数据表中的主键如果没有类似的命名,并且也未显示指明主键,则生成失败,引发异常。

如果想要自定义主键列名,则可以使用Key注释[Key] public int MyId { get; set; }Required当要求数据库在字段,不能为空时[Required]public string BookTitle { get; set; }MaxLength 、MinLength设置数据库字段的长度范围[MaxLength(10),MinLength(6)] public string Password { get; set; }NotMapped当创建数据表时,用此属性修饰的属性,不会被创建为数据表字段[NotMapped] public int MyProperty { get; set; }ComplexTypeComplex属性是将一个对象做为另一个对象的属性。

映射到数据库中则子对象表现为多个属性字段。

具体可参考:EF框架step by step(6)—处理实体complex属性[ComplexType] public class Publisher { public string PublisherName { get; set; } public string PublisherAddress { get; set; } } ConcurrencyCheck并发检查允许你标识一个或者多个属性在实体更新时,要进行检查是否与原实体一致。

sqlite ef codefirst 事务操作

sqlite ef codefirst 事务操作

sqlite ef codefirst 事务操作SQLite是一种轻量级的嵌入式关系型数据库管理系统,具有高性能、低内存占用和跨平台等优点。

Entity Framework (EF)是一种ORM(object-relational mapping)框架,它是.NET Framework的一部分,可以非常方便地对数据库进行增删改查等操作,同时支持多种数据库,包括SQLite。

在使用EF进行SQLite开发的过程中,事务操作是非常重要的一部分,可以保证数据的完整性和一致性。

本文将介绍SQLite EF CodeFirst事务操作的具体内容。

1.事务操作概述事务是指一系列操作组成的逻辑单元,这些操作要么都执行成功,要么都不执行。

如果其中有任何一个操作失败,则整个事务都会被回滚。

事务可以保证数据的完整性和一致性,可以避免数据出现不一致的情况。

在SQLite EF CodeFirst中,可以通过DbContext 来创建事务。

2.事务的创建和提交在SQLite EF CodeFirst中,可以通过以下代码创建一个事务:using (var transaction = db.Database.BeginTransaction()) { /* Transaction operations here */ }在这个示例中,使用DbContext的Database属性创建一个事务,使用BeginTransaction方法开始一个事务,并将其赋值给transaction对象。

在事务中,可以执行一系列操作,包括插入、修改和删除等操作。

在操作完成后,可以使用以下代码提交事务:mit();在这个示例中,使用Commit方法提交事务,如果事务中所有的操作都执行成功,则所有的操作都会被提交。

3.事务的回滚如果在事务中出现了错误,可以使用以下代码回滚事务:4.事务的嵌套在SQLite EF CodeFirst中,可以嵌套多个事务。

EF——一个实体对应两张表,两个实体对应一张表06(转)

EF——一个实体对应两张表,两个实体对应一张表06(转)

EF——⼀个实体对应两张表,两个实体对应⼀张表06(转)本篇⽇记我们将详细探讨如何将表现领域的类映射到现有的数据库。

现在的经济形势不是太好,很多公司都取消了开发新系统的预算。

在这种情况下,通常的做法是把原有的⼏个系统修改⼀下做个集成,先凑合⽤着得了。

如果要对原有的系统做功能提升的话,肯定要重⽤原来的数据库结构并做⼀些⼩的改进,在这种情况下我们怎样使⽤Code First 呢?我们可以按照原有系统的业务逻辑和CR(Change Request)中的新业务逻辑建⽴domain中的类,然后使⽤Fluent API把这些类映射到原有数据库的表中,或修改原有系统的数据结构。

我相信通过前⼏篇的⽇记,⼤家已经知道了怎样去⾃定义各个⽅⾯的数据库映射了。

这种⽅法虽然给我们机会重新审视我们的业务逻辑,但是原有系统中许多没有变化的部分也需要按照Code First的⽅法重头创建类并映射到原有的数据表,给我们的开发带来了很多不必要的⼯作量。

为了提⾼我们的开发效率,减少在使⽤Code First升级系统时不必要的⼯作量,微软发明了Entity Framework Power Tools. 这个⼯具可以使⽤反向⼯程,在原有数据库的基础上⽣成Code First中使⽤的纯粹代表domain的类和数据库映射配置。

博客园上有很多关于这个⼯具的介绍,⼤家可以上博客园搜索。

这个⼯具虽然很好,但是他只能帮你减少你的⼯作量,不可能完全替代你的⼯作。

⽐如说原来的数据库中有⼀个表,你经过对业务逻辑的分析,发现表中的字段应该属于两个类,但是你还不能改变现有的数据库结构,这种情况需要你⾃⼰配置数据库映射来搞定。

或者原来数据库中的两个表,在你的新的业务逻辑中属于同⼀个类,也给根据特定的业务逻辑进⾏数据库映射的配置。

所以我今天主要介绍如何解决以上的两个问题。

1.在不修改数据库结构的前提下,如何将两个类映射到同⼀个数据库表。

2.在不修改数据库结构的前提下,如何将⼀个类映射到两个数据库表。

EFCodeFirst系列(2)---CodeFirst的数据库初始化

EFCodeFirst系列(2)---CodeFirst的数据库初始化

EFCodeFirst系列(2)---CodeFirst的数据库初始化1. CodeFirst的默认约定1.领域类和数据库架构的映射约定 在介绍数据库的初始化之前我们需要先了解领域类和数据库之间映射的⼀些约定。

在CodeFirst模式中,约定指的是根据领域类(如Student,Grade类)⾃动配置概念模型的⼀些默认规则。

在上⼀节的⼩栗⼦中,我们没有在领域类中做任何配置,但是EF API帮我们配置了主外键、关系、列的数据类型等,这就是约定在起作⽤。

下表中列除了⼀些默认的CodeFirst约定:默认规则描述Schema EF创建所有的DB对象都放在dbo架构中。

dbo.StudentsTable Name实体名的复数,如Student->StudentsForeign key 默认情况,EF会找和主实体的主键名⼀样名字的列如果没有的话EF创建⼀个导航属性名_导航属性主键形式的外键,如:在dbo.Students表中,外键是Grade_GradeId列顺序EF创建的数据库列的数据和领域类属性的顺序⼀致,唯⼀可能不⼀致的是会把主键放在第⼀位映射(mapping)默认EF会把领域类的所有属性都映射到数据库,可以通过[NotMapped]实现领域类/属性的不映射级联删除默认启⽤所有的类型关系下表显⽰了C#数据类型到SqlServer数据类型的映射:bool bitbyte tinyintshort smallintint intlong bigintfloat realdouble floatdecimal decimal(18,2)string nvrchar(Max)datetime datetimebyte[]varbinary(Max)下图显⽰了领域类和数据库架构的映射:2.⼀些补充当我们使⽤导航属性时,EF6中把1对多关系作为默认关系。

注意:EF6中不包含1对1,多对多的默认关系,我们需要⾃⼰通过Fluent API或者注释属性进⾏配置。

转:EF调用存储过程、函数

转:EF调用存储过程、函数

转:EF调⽤存储过程、函数⼀.ef4.1 codeFirst 修改表结构增加字段等 EF code first需要重新⽣成库导致数据丢失的问题说这个问题前⾸先先说下我使⽤ef4.1 codefirst的⽬的. 是因为可以有更纯净的POCO 不再有EDMX这些东西⽽不是真正的⽤ code first 先有代码再⽣成数据库.所以我虽然使⽤的是codefirst 但是本质依然是数据库优先.所以这个被问的很多的问题解决办法其实是⾮常简单的.只要你的数据库已经存在了那么即使你⽤code first ef 也不会给你去⽣成数据库的.这个时候你增加表字段甚⾄增加表只要把实体类也相应的修改则数据库⾥的数据是不会被清空的.说下我的开发步骤先设计数据库并建⽴数据库=>通过EF⼯具⽣成映射和实体类=>开发代码当遇到修改时=> 先修改数据库如添加字段或表等=>再修改实体类=>继续开发这样就不会有重新⽣成数据的烦恼了⽽且项⽬⾥也不会出现edmx~还有使⽤EF4.3 的数据迁移功能也可以完美解决~⼆.ef4.1 没有了edmx等复杂的东西变得简单⼲净但如何使⽤存储过程,存储过程可以返回表可以返回数值也有可能是执⾏修改删除增加等该怎么做?说这个问题前依然先说下我的观点.个⼈认为既然使⽤orm框架就应该把业务逻辑等都放到业务逻辑层⽽不应该再使⽤存储过程。

我更偏重重业务逻辑层轻存储过程这样的开发~再ef4.0⾥添加存储过程⽐较容易有edmx 调⼀调存储过程就添加上了但是在ef4.1⾥只有⼲净的poco 不再有edmx了改怎么办呢?尤其是存储过程可以是查表查值或者执⾏修改删除.⼀个⼀个来解决1.执⾏返回表类型的存储过程先上存储过程随⼿写的⼀个最简单的Create PROCEDURE [dbo].[ProSelectStu]@StudentID intASBEGINSelect Student.* from Enrollment,Studentwhere Enrollment.StudentID=Student.StudentID and Enrollment.StudentID=@StudentIDENDGO执⾏存储过程的⽅法是⽤直接执⾏sql的⽅式我在我的⽂章第九篇有过详细的介绍~⼤家可以先去看下执⾏表的存储过程其实是⾮常强⼤的延迟加载等都有体现博客园的陆⽼师已经写了写的⾮常清楚了~我这⾥就不再写了⼤家可以去他那看下提供个连接~2.执⾏返回值的存储过程先上存储过程CREATE PROCEDURE [dbo].[ProSelectCount]@StuId intASBEGINselect COUNT(*) from Enrollment where StudentID=@StuIdEND⼀个简单的查询数量这⾥⽤sqlQuery 执⾏访问数据库因为需要提供返回类型⽽我们返回的是int 所以先得到int的类型3.执⾏增删改CREATE PROCEDURE [dbo].[ProDel]@stuId int,@courseId intASBEGINDELETE FROM [WLFSchool].[dbo].[Enrollment]where StudentID=@stuId and CourseID=@courseIdEND这个⽤的是操作数据库返回受影响⾏数三.ef4.1 如何使⽤数据库视图?每个视图都要去建⽴对应的实体类么?有简单的⽅法么?先说下最传统的⽅法只需把视图当成表建⽴对应的实体类然后加到dbcontext ⾥即可。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

EF Code First 学习笔记:约定配置要更改EF中的默认配置有两个方法,一个是用Data Annotations(在命名空间ponentModel.DataAnnotations;),直接作用于类的属性上面;还有一个就是Fluent API,通过新增相应的配置类来覆盖默认配置。

现在我们用这两个来对比了解EF中的约定配置。

主键:KEYData Annotations:通过Key关键字来标识一个主键[Key]public int DestinationId { get; set; }Fluent API:public class BreakAwayContext : DbContext{public DbSet<Destination> Destinations { get; set; }public DbSet<Lodging> Lodgings { get; set; }protected override void OnModelCreating(DbModelBuilder modelBuilder){//Fluent APImodelBuilder.Entity<Destination>().HasKey(d => d.DestinationId);base.OnModelCreating(modelBuilder);}}外键Data Annotations:public int DestinationId { get; set; }[ForeignKey("DestinationId")]public Destination Destination { get; set; }注意,指定列名存在,如上面的DestinationId,则类中必须存在名称为DestinationId的属性。

Fluent API:modelBuilder.Entity<Lodging>().HasRequired(p =>p.Destination).WithMany(p=>p.Lodgings).HasForeignKey(p => p.DestinationId);长度Data Annotations:通过StringLength(长度),MinLength(最小长度),MaxLength(最大长度)来设置数据库中字段的长度。

[MinLength(10),MaxLength(30)]public string Name { get; set; }[StringLength(30)]public string Country { get; set; }Fluent API:没有设置最小长度这个方法。

modelBuilder.Entity<Destination>().Property(p => ).HasMaxLength(30);modelBuilder.Entity<Destination>().Property(p =>p.Country).HasMaxLength(30);非空Data Annotations:用Required来标识,还可以设置是否可允许空字符串,显示错误消息等。

[Required]public string Country { get; set; }[Required(ErrorMessage="请输入描述")]public string Description { get; set; }Fluent API:modelBuilder.Entity<Destination>().Property(p => p.Country).IsRequired();数据类型Data Annotations:TypeName//将string映射成ntext,默认为nvarchar(max)[Column(TypeName = "ntext")]public string Owner { get; set; }Fluent API:modelBuilder.Entity<Lodging>().Property(p => p.Owner).HasColumnType("ntext"); 表名Data Annotations:Table[Table("MyLodging")]public class Lodging{public int LodgingId { get; set; }public string Name { get; set; }public string Owner { get; set; }public decimal Price { get; set; }public bool IsResort { get; set; }public Destination Destination { get; set; }}Fluent API:modelBuilder.Entity<Lodging>().ToTable("MyLodging");列名Data Annotations:Column[Column("MyName")]public string Name { get; set; }Fluent API:modelBuilder.Entity<Lodging>().Property(p =>).HasColumnName("MyName");自增长如果主键是int类型,EF为默认设置为增长。

但如果是GUID类型,则要显示的设置自增长。

Data Annotations:DatabaseGeneratedpublic class Person{[Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)]public Guid SocialId { get; set; }public string FirstName { get; set; }public string LastName { get; set; }}看看创建数据的脚本,会加一句ALTER TABLE[dbo].[People]ADD DEFAULT (newid()) FOR[SocialId]Fluent API:modelBuilder.Entity<Person>().Property(p =>p.SocialId).HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);忽略列映射类中有些属性,特别是一些通过计算或合并列得出的结果,我们并不需要其记录到数据库中,就可以通过配置不让它生成在数据库中。

Data Annotations:NotMapped[NotMapped]public string Name{get{return FirstName + "" + LastName;}}Fluent API:NotMappedmodelBuilder.Entity<Person>().Ignore(p => );忽略表映射对于不需要映射到数据库中的表,我们也可以取消其映射。

Data Annotations:[NotMapped]public class Person{[Key]public Guid SocialId { get; set; }public string FirstName { get; set; }public string LastName { get; set; }}Fluent API:modelBuilder.Ignore<Person>();时间戳时间戳只对数据类型为byte[]的属性有效,并且一个类中只能有一个设置为时间戳的属性。

Data Annotations:Timestamp[Timestamp]public Byte[] TimeStamp { get; set; }Fluent API:modelBuilder.Entity<Lodging>().Property(p => p.TimeStamp).IsRowVersion();复杂类型Data Annotations:ComplexType[ComplexType]public class Address{public string Country { get; set; }public string City { get; set; }}Fluent API:plexType<Address>();Entity Framework 复杂类型为了说明什么是复杂属性,先举一个例子。

public class CompanyAddress{public int ID { get; set; }public string CompanyName { get; set; }public string StreetAddress { get; set; }public string City { get; set; }public string State { get; set; }public string ZipCode { get; set; }}public class FamilyAddress{public int ID { get; set; }public string StreetAddress { get; set; }public string City { get; set; }public string State { get; set; }public string ZipCode { get; set; }}上面有两个类:公司地址和家庭地址,它们有四个相同的属性:StreetAddress、City、State、ZipCode。

映射到数据库中的结构如图:这里,我们可以将这四个属性集合成一个复杂属性Address,修改后的类为:public class CompanyAddress{public int ID { get; set; }public string CompanyName { get; set; }public Address Address { get; set; }}public class FamilyAddress{public int ID { get; set; }public Address Address { get; set; }}[ComplexType]public class Address{public string StreetAddress { get; set; }public string City { get; set; }public string State { get; set; }public string ZipCode { get; set; }}此时,所生成的数据库如图:可以看到,两张表中仍然具有相应的地址属性信息。

相关文档
最新文档