首页 > 代码库 > 【步步为营 Entity Framework+Reporting service开发】-(2) Code Fir
【步步为营 Entity Framework+Reporting service开发】-(2) Code Fir
也许有人问,为什么要用EF创建爱你数据表,code first好处是什么?
使用EF创建数据库/表,只需要设计简单的C#类,再表内容变化的时候他会自动更新数据库结构,并且保留原有数据。
EF很强大,支持主外键并且能生成和db里一样的数据类型。由于我们这两个表简单,关于进阶的知识我会放在这篇文章的底部作为附录。
根据需求,我们有两种 input 文件。一种是trend 的一种是bar的 我们先来看看这两种文件里的数据:
Trend :
id taskid taskname time b1 equal b2 uncertain grandtotal 0 1 task1 2012-6-27 200 300 280 220 1000
Bar :
KeyWord B1Better Equal B2Better Winner 联众 2 0 3 0 0 B1 疯狂倒计时 0 0 3 0 0 B2 张娜拉 0 1 2 2 0 B1 截图软件 1 0 1 1 2 B2
我们需要show 2个 chart。
那么我们设计2个表来存储 trend chart 和barchart 的数据,名为Trend 和Bar(本来应该是3个表。由于我们是为了自己练习,设计2个就好。)
到这里,我才发现我们还没为我们的project 起名字呢。叫什么好呢?我们就叫 ReportingSyncer吧。
Reporting(报表),sync(同步),为什么加er?现在的project 命名的时候往往都拟人化,显得生动外加比较给力。
【开始动手】
打开vs 2010创建一个新的class library 命名为ReportingDBManager。删除自动生成的class1.cs 。
修改sln(解决方案的名称为ReportingSyncer)。
修改命名空间:右键点击ReportingDBManager。properties(属性)->Application:CnBlogsDemos.ReportingDBManager。为啥要改?因为引用起来方便一点,而且也显得专业:)
现在你的sln应该是这样
添加Entity Framework 引用,得到这个dll 有两种方法:
使用NuGet ,或者去下载一个dll。在这里我使用Nuget ,EF最新版是4.3.1
【创建表的映射类】
添加完引用之后,我们就开始创建我们的表类了。
添加两个class ,名为 Trend 和 Bar。
对应上边input 文件的类型,我们设计两张 匹配的表。
bar.cs:
namespace CnBlogsDemos.ReportingDBManager { using System.ComponentModel; using System.ComponentModel.DataAnnotations; public class Bar { [Key] [DatabaseGenerated(DatabaseGeneratedOption.Identity)] //主键 自增 public int ID { get; set; } public int TaskID { get; set; } [MaxLength(200)] public string TaskName { get; set; } /*有朋友要问了,导入文件里明明没有以上两个字段,为什么要设定他们? 因为导入的时候是根据每个task 导入的,我们会在commandline里数据task id 和task name 这样才可以让两个表联系起来,后期好做报表的drill down (钻入) */ [MaxLength(500)] public string KeyWord { get; set; } public int B1Better { get; set; } public int Equal { get; set; } public int B2Better { get; set; } [MaxLength(50)] public string Winner { get; set; } public string type { get; set; } [DefaultValue(true)] public bool IsActive { get; set; } } }
trend.cs
namespace CnBlogsDemos.ReportingDBManager { using System; using System.ComponentModel; using System.ComponentModel.DataAnnotations; public class Trend { public int id { get; set; } public int TaskID { get; set; } public string TaskName { get; set; } public DateTime Time { get; set; } public int B1Better { get; set; } public int Equal { get; set; } public int B2Better { get; set; } public int UnCertain { get; set; } public int GrandTotal { get; set; } [MaxLength(50)] public string type { get; set; } [DefaultValue(true)] public bool IsActive { get; set; } } }
两个表类创建好了。如何和数据库联系到一块呢?我们需要使用EF创建一个dbcontext类了。
添加新类:DbStoreContext.cs
namespace CnBlogsDemos.ReportingDBManager { using System.Data.Entity; using System.Data.Entity.Migrations; internal sealed class ReportingDbMigrationsConfiguration : DbMigrationsConfiguration<DbStoreContext> { public ReportingDbMigrationsConfiguration() { AutomaticMigrationsEnabled = true; AutomaticMigrationDataLossAllowed = true; } } public class DbStoreContext : DbContext { public DbStoreContext() : base("name=ReportingDataBase") { Database.SetInitializer<DbStoreContext>( new MigrateDatabaseToLatestVersion<DbStoreContext, ReportingDbMigrationsConfiguration>()); this.Configuration.LazyLoadingEnabled = false; } public DbSet<Bar> Bars { get; set; } public DbSet<Trend> Trends { get; set; } } }
上边的两个Dbset 就是我们要创建的两个表。
检查项目中app.config文件,我们会看到:
<entityFramework> <defaultConnectionFactory type="System.Data.Entity.Infrastructure.SqlConnectionFactory, EntityFramework"> <parameters> <parameter value="Data Source=.\SQLEXPRESS; Integrated Security=True; MultipleActiveResultSets=True" /> </parameters> </defaultConnectionFactory> </entityFramework>
EF默认指定的数据库是本地的Express。我们可以更改成其他标准数据库或者是远程数据库(当然,你要有权限哦)。
我们想在另一个project 里指定数据库连接。先把这个appconfig删除。
有朋友要问了,什么时候能生成DB,table啊?我怎么看不见?
别急,在我们第一次调用这个dbcontext 类的时候就会创建/更新啦!
我会在下一章做讲解。
【附录】
EF创建table 时候的一些技巧,查了好多资料,希望能帮助大家:
主键:
[Key] public int EngineID { get; set; }
自增主键:
[Key,DatabaseGenerated(DatabaseGeneratedOption.None)] public int EngineID { get; set; }
可以编辑的主键(默认是readonly)
[Key,Editable(true),DatabaseGenerated(DatabaseGeneratedOption.None)] public int EngineID { get; set; }
非空字段:
[Required] public string EngineName { get; set; }
限定长度的非空字段:
[Required, MaxLength(256)] public string EngineName { get; set; }
外键比较特殊,需要解释一下两个table之间的关系。
table1包含 一个 字段 taskID。
table task 的主键是taskID。需要创建爱你一个 task类型的字段。关系如下:
public class Table1 { [Required, ForeignKey("Task")] public int TaskID { get; set; } public virtual Task Task { get; set; } } public class Task { [Key,DatabaseGenerated(DatabaseGeneratedOption.Identity)] public int TaskID { get; set; } }
时间戳:
[ConcurrencyCheck] [Timestamp] public byte[] TimeStamp { get; set; }
c# 里的 int32 对应 db 里的int 。int16 对应 smallint,bool 对应bit,byte[]对应binary等等。
参考页面:http://www.asp.net/web-api/overview/getting-started-with-aspnet-web-api;http://qingqingquege.cnblogs.com/p/5933752.html;https://docs.microsoft.com/zh-cn/aspnet/mvc/overview/releases/how-to-upgrade-an-aspnet-mvc-4-and-web-api-project-to-aspnet-mvc-5-and-web-api-2
【步步为营 Entity Framework+Reporting service开发】-(2) Code Fir