EF从数据库生成模型步骤:
1.数据库里有一个UserInfo表:
2.右击Model文件夹 - 新建 - Ado.net数据模型:
3.
4.
5.
6.
7.
8.Modle文件夹会生成两个类文件:EFTest.cs是数据库上下文类文件。UserInfo是实体类。
数据库上下文类:
namespace EFTest.Models { using System; using System.Data.Entity; using System.ComponentModel.DataAnnotations.Schema; using System.Linq; public partial class EFTest : DbContext { public EFTest() : base("name=MyContext") { } public virtual DbSet<UserInfo> UserInfo { get; set; } protected override void OnModelCreating(DbModelBuilder modelBuilder) { } } }
实体类:
namespace EFTest.Models { using System; using System.Collections.Generic; using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations.Schema; using System.Data.Entity.Spatial; [Table("UserInfo")] public partial class UserInfo { [DatabaseGenerated(DatabaseGeneratedOption.None)] public int Id { get; set; } [StringLength(10)] public string Name { get; set; } public int? Age { get; set; } public DateTime? Birthday { get; set; } } }
Web.config生成的连接字符串:
<connectionStrings> <add name="MyContext" connectionString="data source=.;initial catalog=EFTest;user id=sa;password=123456;MultipleActiveResultSets=True;App=EntityFramework" providerName="System.Data.SqlClient" /> </connectionStrings>
Controller中使用linq查询和Lambda方法两种方式进行查询:(可连接数据库进行测试Linq写法与Lambda方式的相互转换工具下载:LINQPad) LINQPad使用教程>>
using System; using System.Collections.Generic; using System.Data.Entity; using System.Linq; using System.Web; using System.Web.Mvc; using t2_EFTest.Models; namespace t2_EFTest.Controllers { public class UserInfoController : Controller { // GET: /UserInfo/ public ActionResult Index() { //MyContext myContext=new MyContext(); //查询语法 //var list = from abc in myContext.UserInfo // select abc; //方法语法 //var list = myContext.UserInfo.Select(u => u);
//建议:声明父类型的变量,指向子类型的对象 (面向多态的开始)
//// DbSet<UserInfo> UserInfo { get; set; } //DbContext dbContext=new MyContext(); ////DbSet<TEntity> Set<TEntity>() //dbContext.Set<UserInfo>();
IQueryable<UserInfo> list; //创建上下文对象 DbContext dbContext=new MyContext(); //基本查询 //list = from userInfo in dbContext.Set<UserInfo>() // select userInfo; //单条件查询 //list = from userInfo in dbContext.Set<UserInfo>() // where userInfo.Uid>2 // select userInfo; //多条件 //list = from userInfo in dbContext.Set<UserInfo>() // where userInfo.Uid > 2 && userInfo.UName.Length > 2 // select userInfo; //查询单列 //var list1 = from userInfo in dbContext.Set<UserInfo>() // select userInfo.Uid; //查询多列 //var list1 = from useriInfo in dbContext.Set<UserInfo>() // select new UserInfoViewModel() // { // Uid=useriInfo.Uid, // UName=useriInfo.UName // }; //分页 var list1 = from userInfo in dbContext.Set<UserInfo>() select userInfo; list1 = list1.OrderByDescending(u=>u.Uid).Skip(2).Take(3); //先排序,后取数据 分页是Lambda特有的
return View(list1); } public ActionResult Index2() { DbContext dbContext=new MyContext(); //基本查询 var list1 = dbContext.Set<UserInfo>(); IQueryable<UserInfo> list; //单条件 list = list1.Where(u => u.Uid > 2); //多条件 //list = list1.Where(u => (u.Uid > 2) || (u.UName.Contains("龙"))); //list = list1.Where(u => u.Uid > 2) // .Where(u => u.UName.Contains("龙")); //查询自定义列 //list = list1.select(u => new userinfoviewmodel() //展示部分列的话,可以新建一个model类字段为需要展示的字段 //{ // uid = u.uid, // uname = u.uname //}); return View(list); } } }
View中的显示:
Index:
@using t2_EFTest.Models @*model IQueryable<t2_EFTest.Models.UserInfo>*@ @{ Layout = null; } <!DOCTYPE html> <html> <head> <meta name="viewport" content="width=device-width" /> <title>Index</title> </head> <body> <div> <table border="1"> <tr> <th>编号</th> <th>姓名</th> </tr> @foreach (var userInfo in Model) { //var ui = userInfo as UserInfoViewModel; <tr> <td>@userInfo.Uid</td> <td>@userInfo.UName</td> </tr> } </table> </div> </body> </html>
Index2:
@model IQueryable<t2_EFTest.Models.UserInfo> @{ Layout = null; } <!DOCTYPE html> <html> <head> <meta name="viewport" content="width=device-width" /> <title>Index2</title> </head> <body> <div> <table border="1"> <tr> <th>编号</th> <th>姓名</th> </tr> @foreach (var userInfo in Model) { <tr> <td>@userInfo.Uid</td> <td>@userInfo.UName</td> </tr> } </table> </div> </body> </html>
表NewsType与NewInfo必须建立外键关系才能生成导航属性:
生成的NewsInfo类:
namespace t2_EFTest.Models { using System; using System.Collections.Generic; public partial class NewsInfo { public int nid { get; set; } public string nTitle { get; set; } public int nTid { get; set; } public virtual NewsType NewsType { get; set; } } }
生成的NewsType类:
namespace t2_EFTest.Models { using System; using System.Collections.Generic; public partial class NewsType { public NewsType() { this.NewsInfo = new HashSet<NewsInfo>(); } public int tid { get; set; } public string tTitle { get; set; } public virtual ICollection<NewsInfo> NewsInfo { get; set; } } }
导航属性Controller部分:
using System; using System.Collections.Generic; using System.Data.Common; using System.Data.Entity; using System.Data.Entity.Infrastructure; using System.Linq; using System.Web; using System.Web.Mvc; using t2_EFTest.Models; namespace t2_EFTest.Controllers { public class NewsInfoController : Controller { // GET: /NewsInfo/ public ActionResult Index() { DbContext dbContext=new MyContext(); //var list = from newsInfo in dbContext.Set<NewsInfo>() // join typeInfo in dbContext.Set<t2_EFTest.Models.NewsType>() on newsInfo.nTid equals typeInfo.tid // select newsInfo //; //from后面的in一定要是一个集合类型的对象,才可以连接 //var list = from newsType in dbContext.Set<NewsType>() // from newsInfo in newsType.NewsInfo // select new // { // NTitle = newsInfo.nTitle, // TTitle = newsType.tTitle // }; var list = from newsInfo in dbContext.Set<NewsInfo>() select new NewsTypeViewModel //自定义显示模型来显示部分字段 { NTitle=newsInfo.nTitle, TTitle=newsInfo.NewsType.tTitle }; return View(list); } } }
导航属性View部分:
@model IQueryable<t2_EFTest.Models.NewsTypeViewModel> @{ Layout = null; } <!DOCTYPE html> <html> <head> <meta name="viewport" content="width=device-width" /> <title>Index</title> </head> <body> <div> @Model.GetType() <hr/> <table border="1"> @foreach (var newsinfo in Model) { <tr> <td>@newsinfo.NTitle</td> <td>@newsinfo.TTitle</td> </tr> } </table> </div> </body> </html>
自定义的NewsTypeViewModel:
using System; using System.Collections.Generic; using System.Linq; using System.Web; namespace t2_EFTest.Models { public class NewsTypeViewModel { public string NTitle { get; set; } public string TTitle { get; set; } } }
单表增删改查操作:
View的Index部分:
@using t2_EFTest.Models @model IQueryable<t2_EFTest.Models.UserInfo> @{ Layout = null; } <!DOCTYPE html> <html> <head> <meta name="viewport" content="width=device-width" /> <title>Index</title> </head> <body> <div> @Html.ActionLink("添加","Add","UserInfoCrud") <hr/> <table border="1"> <tr> <th>编号</th> <th>姓名</th> <th>修改</th> <th>删除</th> </tr> @foreach (UserInfo userInfo in Model) { <tr> <td>@userInfo.Uid</td> <td>@userInfo.UName</td> <td> @Html.ActionLink("修改","Edit","UserInfoCrud", new RouteValueDictionary(new {[email protected]}),null) </td> <td> @Html.ActionLink("删除", "Remove", "UserInfoCrud", new RouteValueDictionary(new { [email protected] }),null) </td> </tr> } </table> </div> </body> </html>
Add部分:
@model t2_EFTest.Models.UserInfo @{ Layout = null; } <!DOCTYPE html> <html> <head> <meta name="viewport" content="width=device-width" /> <title>Add</title> </head> <body> <div> @using (Html.BeginForm("Add", "UserInfoCrud", FormMethod.Post)) { <span>姓名:</span> @Html.TextBoxFor(u=>u.UName) <br/> <input type="submit" value="添加"/> } </div> </body> </html>
Edit
@model t2_EFTest.Models.UserInfo @{ Layout = null; } <!DOCTYPE html> <html> <head> <meta name="viewport" content="width=device-width" /> <title>Edit</title> </head> <body> <div> @using (Html.BeginForm("Edit", "UserInfoCrud", FormMethod.Post)) { <span>编号:</span> @Model.Uid @Html.HiddenFor(u=>u.Uid) <br/> <span>姓名:</span> @Html.TextBoxFor(u=>u.UName) <br/> <input type="submit" value="修改"/> } </div> </body> </html>
增删改查Controller部分:
using System; using System.Collections.Generic; using System.Data.Entity; using System.Data.Entity.Migrations; using System.Linq; using System.Web; using System.Web.Mvc; using System.Web.Routing; using t2_EFTest.Models; namespace t2_EFTest.Controllers { public class UserInfoCrudController : Controller { DbContext dbContext=new MyContext(); // GET: /UserInfoCrud/ public ActionResult Index() { var list = dbContext.Set<UserInfo>(); return View(list); } public ActionResult Add() { return View(); } [HttpPost] public ActionResult Add(UserInfo userInfo) { dbContext.Set<UserInfo>().Add(userInfo); int result=dbContext.SaveChanges();//如果内存中的数据发生了变化,并且希望将这个变化映射到数据库,需要执行这个方法 if (result > 0) { return Redirect(@Url.Action("Index", "UserInfoCrud")); } else { return Redirect(@Url.Action("Add")); } } public ActionResult Edit(int id) { ViewData.Model = dbContext.Set<UserInfo>() .Where(u => u.Uid == id).FirstOrDefault(); return View(); } [HttpPost] public ActionResult Edit(UserInfo userInfo) { dbContext.Set<UserInfo>().AddOrUpdate(userInfo); int result = dbContext.SaveChanges(); if (result > 0) { return Redirect(Url.Action("Index")); } else { return Redirect(Url.Action("Edit", new RouteValueDictionary(new { id = userInfo.Uid }))); } } public ActionResult Remove(int id) { var userInfo = dbContext.Set<UserInfo>() .Where(u => u.Uid == id) .FirstOrDefault(); dbContext.Set<UserInfo>().Remove(userInfo); dbContext.SaveChanges(); return Redirect(Url.Action("Index")); } } }
EF生成的实体部分:
namespace t2_EFTest.Models { using System; using System.Collections.Generic; public partial class UserInfo { public int Uid { get; set; } public string UName { get; set; } } }
用状态跟踪的方式来修改带导航属性的数据: (上面AddOrUpdate等这种方式实质还是用的状态跟踪方式,只是做了封装而已)
View部分:
@model IQueryable<t2_EFTest.Models.NewsInfo> @{ Layout = null; } <!DOCTYPE html> <html> <head> <meta name="viewport" content="width=device-width" /> <title>Index</title> </head> <body> <div> <table border="1"> <tr> <th>编号</th> <th>标题</th> <th>分类</th> <th>修改</th> </tr> @foreach (var newsInfo in Model) { <tr> <td>@newsInfo.nid</td> <td>@newsInfo.nTitle</td> <td>@newsInfo.NewsType.tTitle</td> <td> @Html.ActionLink( "修改", "Edit", "NewsInfoCrud", new RouteValueDictionary(new {[email protected]}), null ) </td> </tr> } </table> </div> </body> </html>
@model t2_EFTest.Models.NewsInfo @{ Layout = null; } <!DOCTYPE html> <html> <head> <meta name="viewport" content="width=device-width" /> <title>Edit</title> </head> <body> <div> @using (Html.BeginForm("Edit", "NewsInfoCrud", FormMethod.Post)) { @Model.nid @Html.HiddenFor(n=>n.nid) <br/> @Html.TextBoxFor(n=>n.nTitle) <br/> <input type="submit" value="修改"/> } </div> </body> </html>
Controller部分:
using System; using System.Collections.Generic; using System.Data; using System.Data.Entity; using System.Linq; using System.Web; using System.Web.Mvc; using t2_EFTest.Models; namespace t2_EFTest.Controllers { public class NewsInfoCrudController : Controller { // GET: /NewsInfoCrud/ DbContext dbContext=new MyContext(); public ActionResult Index() { ViewData.Model = from newsInfo in dbContext.Set<NewsInfo>() select newsInfo; return View(); } public ActionResult Edit(int id) { ViewData.Model= dbContext.Set<NewsInfo>() .Where(n => n.nid == id) .FirstOrDefault(); return View(); }
[HttpPost] public ActionResult Edit(NewsInfo newsInfo) { //使用状态方式进行修改 dbContext.Set<NewsInfo>().Attach(newsInfo); //dbContext.Entry(newsInfo).State = EntityState.Modified; //这种方式只适合修改所有字段,包括外键字段,不然会报错 dbContext.Entry(newsInfo).Property("nTitle").IsModified = true; //这种方式适合修改部分列 dbContext.Entry(newsInfo).Property("nTitle").CurrentValue = newsInfo.nTitle; dbContext.SaveChanges(); return Redirect(Url.Action("Index")); } } }
IQueryable<T>可以使用匿名表达式
延迟加载View部分:
@{ Layout = null; } <!DOCTYPE html> <html> <head> <meta name="viewport" content="width=device-width" /> <title>Index</title> </head> <body> <div> @*@foreach (var userInfo in ViewBag.list) { @userInfo.Uid }*@ <hr/> @* @foreach (var userInfo in ViewBag.list) { @userInfo.Uid }*@ <hr/> @* @foreach (var userInfo in ViewBag.list2) { @userInfo.Uid }*@ @*@foreach (var newsInfo in ViewBag.list3) { @newsInfo.NewsType.tid }*@ </div> </body> </html>
延迟加载controller部分:
using System; using System.Collections.Generic; using System.Data.Common.CommandTrees; using System.Data.Entity; using System.Linq; using System.Web; using System.Web.Mvc; using t2_EFTest.Models; namespace t2_EFTest.Controllers { public class DelayLoadController : Controller { // // GET: /DelayLoad/ public ActionResult Index() { DbContext dbContext=new MyContext(); //延迟加载:如果不使用数据,则只是拼接sql语句,不会将结果集拿到内存中来 //IQueryable<UserInfo> list = dbContext.Set<UserInfo>() // .OrderByDescending(u => u.Uid)//默认会将lambda表达式封装成Expression对象,而调用IQueryable<T>的方法 // .Skip(2) // .Take(3); //ViewBag.list = list.ToList(); //结尾增加.ToList或FirstOrDefault()来切换为非延迟加载,直接加载到内存中。 IEnumerable<UserInfo> list2 = dbContext.Set<UserInfo>() .AsEnumerable() .OrderByDescending(u => u.Uid) .Skip(2) .Take(3); ViewBag.list2 = list2; //导航属性默认也会使用延迟加载 IQueryable<NewsInfo> list3 = dbContext.Set<NewsInfo>(); ViewBag.list3 = list3.Include(n=>n.NewsType).ToList(); return View(); } } }
.edmx文件实质是xml文件,里面包含数据模型定义、概念实体模型和映射关系。
DbContext把Linq语句转换成Sql语句来执行
可以进行属性设置:
字段设置完成后,转换所有T4模板:
生成了实体类文件:
表之间添加关系:一对一、一对多、多对多
根据模型生成数据库: