首页 > 代码库 > 【步步为营 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