前面两篇文章介绍了DataBase-First例子,这里就介绍Code-First。
个人简单理解:就是在程序中编写代码,然后在数据库中生成相应的表、字段、约束等等。听上去蛮神奇的。Now,begin。
这里为了方便,还是用控制台,VS2010与Sql 2005。
为了学习EF Code-First 方法,我们首先需要添加引用,EntityFramework.dll,点击下载
由于是控制台程序,我们需要在App.config文件中写好数据库连接字符串(web程序不需要)。
<add name="TestStudent" connectionString="data source=(local);Initial Catalog=TestStudent;User Id=sa;Password=123456;
persist security info=True;" providerName="System.Data.SqlClient" />
这个数据库中,有用户表User,以及这些学生的成绩表Grade,一对多的关系。
首先先看下面的代码
public class User { [Key] [DatabaseGenerated(DatabaseGeneratedOption.Identity)] public int Id { get; set; } public int UserId { get; set; } public string UserName { get; set; } public virtual ICollection<Grade> Grade { get; set; } } public partial class Grade { [Key] [DatabaseGenerated(DatabaseGeneratedOption.Identity)] public int GradeId { get; set; } public string SourceName { get; set; } public double SourceGrade { get; set; } public int GUserId { get; set; } [ForeignKey("GUserId")] public virtual User User { get; set; } }
按照Code-First规则,一旦运行此程序,就会生成表名为User、Grade的数据表,User表里面有Id,UserId,UserName三个字段,其中Id是User表的主键,并且是自增。如果你不希望此数据表名为User,可以通过在类名前加上[Table("StudentInfo")],则生成的数据表名为StudentInfo。
其中
代码 public virtual ICollection<Grade> Grade { get; set; } ---》表示该列表延迟加载。
[ForeignKey("GUserId")]
public virtual User User { get; set; } -----》表示列GUserId是User表的外键。
那么,如何创建数据库呢,如下代码
public class StudentDbContext : DbContext { public StudentDbContext() : base("name=TestStudent") { this.Database.CreateIfNotExists(); } public IDbSet<User> User { get; set; } public IDbSet<Grade> Grade { get; set; } }
这里,我们写了一个类 StudentDbContext ,继承类DBContext。
其中 DbContext : IDisposable, IObjectContextAdapter
接口 IObjectContextAdapter的原型
public interface IObjectContextAdapter
{
System.Data.Objects.ObjectContext ObjectContext { get; }
}
因此,ObjectContext是师祖。
这里需要注意一下,name="XXX"的名称要与连接数据库的名称一样,否则可能会有小问题出现。
“this.Database.CreateIfNotExists()”表示如果如果不存此数据库,就去创建数据库。
IDbSet原型如下
public interface IDbSet<TEntity> : IQueryable<TEntity>, IEnumerable<TEntity>, IQueryable, IEnumerable where TEntity: class { TEntity Add(TEntity entity); TEntity Attach(TEntity entity); TDerivedEntity Create<TDerivedEntity>() where TDerivedEntity: class, TEntity; TEntity Create(); TEntity Find(params object[] keyValues); TEntity Remove(TEntity entity); ObservableCollection<TEntity> Local { get; } }
在下面,我们就会用到这些方法去操作数据库的内容。
1、添加数据
代码如下
//使用DBContext 里自带的方法操作数据库
var User = new User() { UserId = 1, UserName = "刘德华" }; db.User.Add(User); db.SaveChanges();
//直接使用Sql 语句操作数据库
db.Database.ExecuteSqlCommand("insert into Users(UserId,UserName) values({0},{1})",
new object[] { 2, "xianrongbin" });
2、查询数据
var ListUsers = db.User.ToList<User>(); //var ListUsers = db.Database.SqlQuery<User>("select * from Users").ToList<User>();
foreach (var item in ListUsers) { Console.WriteLine(item.UserName); //var Grades = db.Grade.Where(a=>a.GUserId==item.UserId);
var Grades = from a in db.Grade where a.GUserId == item.UserId select a; foreach (var grade in Grades) { Console.WriteLine(grade.SourceName + " " + grade.SourceGrade); } }
当然,因为两张表存在主外键的关系,我们可以使用类似Sql语句中的join语法,查询数据,代码如下
var query = from s in db.User join c in db.Grade on s.UserId equals c.GUserId //where s.UserId == 1 select new { SID=s.UserId, SName=s.UserName, KMName=c.SourceName, KMScore=c.SourceGrade }; foreach (var item in query) { Console.WriteLine("学生{0} 的{1}成绩是{2}",item.SName,item.KMName,item.KMScore); }
3、修改数据
int userId = 1; User UserModel = db.User.Find(userId); UserModel.UserName = "陈小春"; db.Entry(UserModel).State = EntityState.Modified; db.SaveChanges(); //db.Database.ExecuteSqlCommand("update Users set UserName='刘德华' where Id=2");
4、删除数据
User UserModel = db.User.Find(3); if (UserModel != null) { db.Entry(UserModel).State = EntityState.Deleted; db.SaveChanges(); }
OK,Code-First例子这里计算讲完了。