Entity Framwork學習筆記

1、First Demo

 

 

 

 

EF從數據庫生成模型步驟:php

1.數據庫裏有一個UserInfo表:css

 

2.右擊Model文件夾 - 新建 - Ado.net數據模型:html

3.vue

 

4.ios

5.c++

 

6.git

 

7.es6

 

8.Modle文件夾會生成兩個類文件:EFTest.cs是數據庫上下文類文件。UserInfo是實體類。web

數據庫上下文類:sql

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)
        {
        }
    }
}
View Code

實體類:

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; }
    }
}
View Code

 

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>
View Code

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>
View Code

 

 

表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 {id=@userInfo.Uid}),null)
                    </td>
                    <td>
                        @Html.ActionLink("刪除",
                        "Remove",
                        "UserInfoCrud",
                        new RouteValueDictionary(new
                        {
                            id=@userInfo.Uid
                        }),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 {id=@newsInfo.nid}),
                        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")); } } }

 

 

2、延遲加載 (用的時候纔去拿數據)

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();
        }

    }
}

 

 

3、EF原理

 

    .edmx文件實質是xml文件,裏面包含數據模型定義、概念實體模型和映射關係。

 

 

 

    DbContext把Linq語句轉換成Sql語句來執行

 

 

 

DB Fisrt:先設計數據庫,而後開發代碼。

 

4、Model Fisrt  (先建數據實體模型,而後建模型去生成數據庫)

能夠進行屬性設置:

 

字段設置完成後,轉換全部T4模板:

生成了實體類文件:

表之間添加關係:一對1、一對多、多對多

 

根據模型生成數據庫:

 

點擊完成

執行生成的Sql腳本建立數據庫:

相關文章
相關標籤/搜索