av 余小章 's 5 år siden
5386
%LOCALAPPDATA%\Microsoft\Microsoft SQL Server Local DB\Instances
"C:\Program Files\Microsoft SQL Server\120\Tools\Binn\SqlLocalDB.exe" create "v12.0"
"C:\Program Files\Microsoft SQL Server\110\Tools\Binn\SqlLocalDB.exe" create "v11.0"
理論上 2014 應該是 v12.0,但事實上是MSSQLLocalDB
v11.0 代表 2012
建立執行個體 SqlLocalDB.exe Projects
查看 Projects 執行個體資訊 SqlLocalDB.exe info Projects
查看已安裝版本 SqlLocalDB.exe versions
2014 %PROGRAMFILES%\Microsoft SQL Server\120\LocalDB\Binn
2012 %PROGRAMFILES%\Microsoft SQL Server\110\LocalDB\Binn
2014
2012
自動安裝2012版本
組態檔加密
限制組態檔的存取權限
Tools→Sql Server
Database Project
dbForge Studio for MySQL
資料庫比較/轉移,需要費用 當多人維護資料庫時很重要
IntelliSense
ER Model
AsNoTracking
資料變更CUD,停用自動偵測變更
context.Configuration.AutoDetectChangesEnabled = false;
無法由快取更新到資料庫
物件快取不驗證
Sample Code:Transaction
TransactionScope
Complete() 認可基礎存放區交易
MySQL 提供的元件不支援 Distributed Transaction
MSDTC 需啟動
DbContextTransaction
Rollback() 回復基礎存放區交易
Commit() 認可基礎存放區交易
關聯
刪除關聯
Sample Code:DeleteRelation
Set Null
把FK找出來設為null
行為:刪除PK,FK設為null
No Action
沒有處理 FK
POCO Proxy FK 設為 Nullable
行為:刪除PK,若未先刪除FK,跳出例外訊息
Cascade
關閉Cascade
使用Fluent API,將WillCascadeOnDelete設為false
modelBuilder.Entity<Identity>()
.HasMany(a => a.IdentityLogs)
.WithRequired(o => o.Identity).HasForeignKey(o => o.IdentityId)
.WillCascadeOnDelete(false);
POCO Proxy FK 設為必填
行為:刪除PK,一併刪除FK
載入關聯
Sample Code:RelationLoading
怎麼選擇?
不確定現階段會使用哪些關聯,選擇消極式載入,可避免一次載入太多實體,程式碼也會比較容易閱讀
但如果載入太多實體,回傳的封包就會越大,這時可切換到消極式載入
當網路有問題,可選擇積極式載入,可減少網路往返
三種載入方式
積極式載入 (Eager loading)
Load() 直接載入關聯表
Include()
var find = context.Products.Include("Orders").FirstOrDefault(o => o.Id == 1)
強型別關聯
弱型別關聯
明確式載入 (Explicitly Loading)
需要關聯資料時,不會自動載入
LazyLoadingEnabled=false
消極式載入 (Lazy Loading)
會造成網路往返頻繁
需要關聯資料時,會自動載入
LazyLoadingEnabled=true
POCO Proxy
長的跟一般POCO不一樣,會像這樣一大串 {System.Data.Entity.DynamicProxies.Student_F2D791D54B1CD734227C45D5844D1724A022D1B411B8F3E88DC3D0B554876802}
自動追蹤變更,預設啟用 context.Configuration.AutoDetectChangesEnabled
自動建立Proxy,預設啟用 context.Configuration.ProxyCreationEnabled
POCO 實體啟用消極式載入,並讓 Entity Framework 在類別中發生變更時追蹤變更
查詢
不查詢快取
如果您在唯讀情節中,並想避免將物件載入 ObjectStateManager 的額外負荷,您可以發出「非追蹤」查詢。變更追蹤可在查詢層級停用。
請注意,即便如此,停用變更追蹤可讓您有效地關閉物件快取。但是當您查詢實體時,將無法從 ObjectStateManager 提取之先前具體化的查詢結果,來略過具體化。如果您重複查詢相同內容中的相同實體,您可能會實際目睹啟用變更追蹤的效能優點。
使用 ObjectContext 進行查詢時,ObjectQuery 和 ObjectSet 執行個體會記住設定的 MergeOption,且針對這些執行個體撰寫的查詢將繼承上層查詢的有效 MergeOption。使用 DbContext 時,可透過在 DbSet 上呼叫 AsNoTracking() 修飾詞來停用追蹤。
使用 IEnumerable
int[] ids = new int[10000];
...
using (var context = new MyContext())
{
var query = context.MyEntities
.Where(entity => ids.Contains(entity.Id));
var results = query.ToList();
...
}
將您的查詢連結至另一個需要重新編譯的查詢
Database.SqlQuery
var q1 = context.Database.SqlQuery<Product>("select * from products");
DbSet
var q = context.Products.AsNoTracking().Where(p => p.Category.CategoryName == "Beverages");
查詢結果不會放入快取,可避免狀態改變而引起的額外記憶體負荷
直接對SQL做查詢
查詢快取
繫結UI
DbSet.Local
適用,資料庫主要修改權,只有單一應用程式
不會返回 EntityState.Deleted 實體
DbSet.Load() 將查詢到的資料cache到DbSet.Local
DbContext.Customers.Load();
context.Posts.Where(p => p.Tags.Contains("entity-framework").Load();
用法
DbSet.SqlQuery
var q2 = context.Products.SqlQuery("select * from products");
For迴圈
LINQ to Entities
查詢相同資料時,快取可發揮校能
第二次的查詢稱為暖查詢,查詢快取
第一次的查尋稱為冷查詢,查詢 DB 實體
存檔
DbContext.SaveChanges()
刪除
DbSet.Remove()
建立
DbSet.Add()
如何使用?
繼承
TPH
父、子類別只產生一個Table
TPT
如果您的模型使用 TPT 繼承,產生的查詢會比使用其他繼承策略所產生的查詢更複雜,而可能導致存放區上的執行時間更長。透過 TPT 模型產生查詢及具體化產生的物件,通常需要更長的時間。
父、子類別都會產生Table,並使用主鍵共享一對一關聯
TPC
主類別不會產生Table,子類別會
Update Schema
MigrateDatabaseToLatestVersion
表示使用 Code First 移轉以將資料庫更新至最新版本之 IDatabaseInitializer
Database.SetInitializer(new MigrateDatabaseToLatestVersion<CustomerDbContext, AppCodeFirst.Migrations.Configuration>());
步驟
Update-Database
Update-Database -Verbose 查看「Code First 移轉」所執行的 SQL
Add-Migration
Add-Migration InitialCreate -IgnoreChanges 建立空的 DbMigration,主要用來更新已存在的Database
Add-Migration AddPostAbstract 最佳猜測建立結構
Add-Migration [有意義的名稱]
Add-Migration InitialCreate 第一次執行新增資料庫移轉
Enable-Migrations
Enable-Migrations -ConnectionStringName DefaultConnection
Enable-Migrations –ContextTypeName [DbContext Class Name]
如果專案裡不只一個 DbContext 類別的話,可以原本的指令後面 DbContext 類別名稱
enable-migrations –ContextTypeName BlogSample.Models.SampleContext
Enable-Migrations -EnableAutomaticMigrations
自動轉移,只對新增欄位有效,刪除、修改無效
連線字串
讀取 Web.config/App.config
預設連接工廠
<defaultConnectionFactory type="System.Data.Entity.Infrastructure.LocalDbConnectionFactory, EntityFramework">
<parameters>
<parameter value="v11.0" />
</parameters>
</defaultConnectionFactory>
類型探索
資料庫初始化
Database.SetInitializer
DropCreateDatabaseIfModelChanges 它只會在模型於資料庫建立後已變更時刪除及重新建立資料庫,並選擇性地重新植入資料庫。
CreateDatabaseIfNotExists 只會在資料庫不存在時重新建立資料庫,並選擇性地重新植入資料庫。 若要植入資料庫,請建立衍生類別並覆寫 Seed 方法。
DropCreateDatabaseAlways IDatabaseInitializer 的實作,只要是初次在應用程式定義域中使用內容,就一定會重新建立資料庫,並選擇性地重新植入資料庫。 若要植入資料庫,請建立衍生類別並覆寫 Seed 方法。
Database.SetInitializer(new DropCreateDatabaseIfModelChanges<SystemDbContext>());
定義DbSet 屬性
public class SystemDbContext : DbContext
{
public DbSet<Identity> Identities { get; set; }
public DbSet<Employee> Employees { get; set; }
public DbSet<Candidate> Candidates { get; set; }
public DbSet<CandidateData> CandidateDatas { get; set; }
public SystemDbContext()
: base("LocalDbConnect")
{
Database.SetInitializer(new DropCreateDatabaseIfModelChanges<SystemDbContext>());
}
}
實作DbContext,繼承 DbContext
建立POCO (Plain Old CLR Objects)
定義關聯
Fluent API
Sample Code:SimpleFluentAPI
Implement EntityTypeConfiguration
Override OnModelCreating
欄位Attribute
Sample Code:UseAttribute
System.ComponentModel.DataAnnotations
StringLength 指定資料欄位中允許的最小和最大字元長度
Required 必填欄位
MinLength 指定屬性中所允許之陣列或字串資料的最小長度
MaxLength 指定屬性中所允許之陣列或字串資料的最大長度
Key 表示唯一識別實體的一個或多個屬性
System.ComponentModel.DataAnnotations.Schema
如何定義 POCO Proxy
Sample Code:DefaultBehavior
多對多
一對多
一對一
關聯性中的「多」端的導覽屬性必須傳回會實作 ICollection 的型別
導覽(navigation)屬性必須宣告為 public、 virtual
當類別的屬性有 Id (不分大小寫)或是後綴詞含有 Id,這個欄位就會變成主索引鍵 PK,若同時有兩個欄位後綴詞帶有 Id,EF 就會自己挑一個來當 PK
預設慣例
Sample Code:SimpleCodeFirst
為什麼要用Code First
缺點
DBA 介入時會造成衝突
必須手動建立POCO
優點
聚焦在業務邏輯
開發期間不需要關心資料庫欄位是否存在 (傳統ADO.NET的做法要改兩個地方,資料庫跟程式碼)
動態建立資料庫
Source Control
彈性大,不受工具影響
Model First
Database First
Demo Database First
LocalDB
安裝 SSDT for SQL 2014(SQL Server Data Tools)
Entity Framework 6.1 from NuGet
安裝 Entity Framework 6.1.0 Tools
ObjectContext
DbContext
Oracle
PostgreSQL
DB2
SQLite
Maria
MySQL
SQL Compact Edtion
SQL Server
在 DbContext 加上Attribute [DbConfigurationType(typeof(MySql.Data.Entity.MySqlEFConfiguration))]
業務邏輯依賴的是Repository Interface,而不是DAL的操作,當資料來源有很多不一樣的資料格式時,程式碼才不需要做變更
UI
人機介面
User Interface
Presention Layer
BLL
Business Logic Layer
DAL
Data Access Layer
Sample Code:SimpleReflrction
徹底瞭解ORM的工作原理
效能提升是需要成本的
在ADO.NET裡面,讀取方式使用 DataReader+Sequential Access 最快
會影響效能的技術
延遲載入 (Lazy Loading) 關聯性物件,不會一次載入,待需要使用時才會動態載入 是優點也是缺點,在適當的情境下使用
SQL Generation,自動產生 SQL 指令
Attribute 宣告自訂對應
Type Converter,列舉型別轉換
Reflection,動態的對應 Property 和 Field
情境: 當PM說要抽換資料庫,由原本的 Sql Server 換成 Mariai,程式會大改,你感覺如何?
回顧一下ADO.NET怎麼寫? Sample Code:ADOConnect