edm存儲
㈠ 在entity framework中怎麼調用存儲過程
一、使用存儲過程的必要性
我們知道EF通過元數據,即概念模型(Concept Model)、存儲模型(Storage Model)和概念/存儲映射(C/S Mapping),和狀態追蹤(State Tracking)機制可以為基於模型的操作自動生成SQL。對於一些簡單的項目開發,這是非常理想的,因為他們完全可以不用關注數據存儲層面的東西,你可以採用一些完全不具有資料庫知識的開發者。但是理想總歸是理想,對於企業級開發來說,我們需要的是對資料庫層面數據的操作有自己的控制。在這方面,我們可以隨便舉兩個典型的場景:
邏輯刪除:對於一些重要的數據,我們可能需要讓它們永久保存。當我們試圖「刪除」這些數據的時候,我們並不是將它們從數據表中移除(物理刪除),而是為這條記錄作一個已經被刪除的標記;
並發處理:為了解決相同的數據在獲取和提交這段時間內被另一個用戶修改或者刪除,我們往往SQL層面增加並發控制的邏輯。比較典型的做法是在每一個表中添加一個VersionNo這樣的欄位,你可以採用TimeStamp,也可以直接採用INT或者GUID。在執行Update或者Delete的SQL中判斷之前獲取的VersionNo是否和當前的一致。
讓解決這些問題,就不能使用EF為我們自動生成的SQL,只有通過使用我們自定義的存儲過程。
二、實現存儲過程自動匹配的必要條件
本篇文章提供的存儲過程自動映射機制是通過代碼生成的方式完成的。說白了,就是讀取原來的.edmx模型文件,通過分析在存儲模型中使用的數據表,導入基於該表的CUD存儲過程;然後再概念/存儲映射節點中添加實體和這些存儲過程的映射關系。那實現這樣的代碼生成,需要具有如下三個固定的映射規則。
數據表名-存儲過程名:這個映射關系幫助我們通過存儲模型中的實體名找到對應CUD三個存儲過程(如果實體是數據表);
數據表列名-存儲過程參數名:當存儲過程被執行的時候,通過這個映射讓概念模型實體某個屬性值作為對應的參數;
存儲過程參數名-版本:當進行參數賦值的時候,通過這個映射決定是使用Original或者Current版本。
在實際的開發過程中,這樣的標准存儲過程一般都是通過代碼生成器生成的(在我的文章《創建代碼生成器可以很簡單:如何通過T4模板生成代碼?[下篇]》中有過相應的實現),它們具有這樣的映射關系。
基於這三種映射關系,我定義了如下一個名為IProcereNameConverter的介面。其中OperationKind是我自定義的一個表示CUD操作類型的枚舉。
1: public interface IProcereNameConverter
2: {
3: string GetProcereName(string tableName, OperationKind operationKind);
4: string GetColumnName(string parameterName);
5: DataRowVersion GetVersion(string parameterName);
6: }
7:
8: public enum OperationKind
9: {
10: Insert,
11: Update,
12: Delete
13: }
按照我們當前項目採用的命名規范,我定義了如下一個默認的DefaultNameConverter。它體現的是這樣的映射關系,比如有個數據表明為T_USER(大寫,單詞之間用「_」隔開,並以T_為前綴),它對應的CUD存儲過程名分別為:P_USER_I、P_USER_U和P_USER_D(大寫,以代表存儲過程的P_為前綴,後綴_I/U/D表示CUD操作類型,中間為去除前綴的表名)。如果列名為USER_ID,參數名為p_user_id(小寫,加p_前綴)。如果需要用Original值為參數賦值,需要將p_前綴改成o_前綴(o_user_id)。
1: public class DefaultNameConverter: IProcereNameConverter
2: {
3: public string GetProcereName(string tableName, OperationKind operationKind)
4: {
5: switch (operationKind)
6: {
7: case OperationKind.Insert:
8: return string.Format("P_{0}_I", tableName.Substring(2));
9: case OperationKind.Update:
10: return string.Format("P_{0}_U", tableName.Substring(2));
11: default:
12: return string.Format("P_{0}_D", tableName.Substring(2));
13: }
14: }
15:
16: public string GetColumnName(string parameterName)
17: {
18: return parameterName.Substring(2).ToUpper();
19: }
20:
21: public DataRowVersion GetVersion(string parameterName)
22: {
23: if(parameterName.StartsWith("o"))
24: {
25: return DataRowVersion.Original;
26: }
27: else
28: {
29: return DataRowVersion.Current;
30: }
31: }
32: }
三、通過T4生成新的.edmx模型
我們採用的基於T4的代碼生成,了解EF的應該對T4不會感到陌生了。如果對代碼生成感興趣的話,可以看看我的文章《與VS集成的若干種代碼生成解決方案[博文匯總(共8篇)]》。這里利用藉助於T4 ToolBox這個開源工具箱,並採用SQL Server SMO獲取存儲過程信息。所有涉及到的文本轉化都實現在如下一個ProcereMappingTemplate類型中,由於內容較多,具體實現就忽略了,有興趣的朋友可能下載源代碼。ProcereMappingTemplate具有兩個構造函數的參數分別表示:源.edmx文件,伺服器和資料庫名,存儲過程的Schema(默認為dbo)和具體的ProcereNameConverter(默認為DefaultNameConverter)。
1: public class ProcereMappingTemplate: Template
2: {
3: public XmlDocument SourceModel { get; private set; }
4: public IProcereNameConverter ProcereNameConverter { get; private set; }
5: public Database Database { get; private set; }
6: public string Schema { get; private set; }
7:
8: public ProcereMappingTemplate(string sourceModelFile, string serverName, string databaseName);
9: public ProcereMappingTemplate(string sourceModelFile, string serverName, string databaseName,
10: IProcereNameConverter procereNameConverter, string schema);
11:
12: protected virtual XElement GenerateStorageModelNode();
13: protected virtual XElement GenerateMappingNode();
14: public override string TransformText()
15: {
16: XElement newStorageModelNode = this.GenerateStorageModelNode();
17: XElement newMappingNode = this.GenerateMappingNode();
18:
19: XmlNode storageModelNode = this.SourceModel.GetElementsByTagName("edmx:StorageModels")[0];
20: storageModelNode.InnerXml = newStorageModelNode.Elements().ToArray()[0].ToString();
21:
22: XmlNode mappingNode = this.SourceModel.GetElementsByTagName("edmx:Mappings")[0];
23: mappingNode.InnerXml = newMappingNode.Elements().ToArray()[0].ToString();
24:
25: this.WriteLine("<?xml version=\"1.0\" encoding=\"utf-8\"?>");
26: this.Write(this.SourceModel.DocumentElement.OuterXml.Replace("xmlns=\"\"",""));
27: return GenerationEnvironment.ToString();
28: }
29: }
在使用過程中,你只需要在tt模板中創建這個ProcereMappingTemplate對象,調用Render方法即可。
1: <#@ template debug="true" hostSpecific="true" #>
2: <#@ output extension=".edmx" #>
3: <#@ assembly name="Microsoft.SqlServer.ConnectionInfo" #>
4: <#@ assembly name="Microsoft.SqlServer.Smo" #>
5: <#@ assembly name="Microsoft.SqlServer.Management.Sdk.Sfc" #>
6: <#@ assembly name="$(TargetDir)Artech.ProcereMapping.dll" #>
7: <#@ import namespace="Artech.ProcereMapping" #>
8: <#@ include file="T4Toolbox.tt" #>
9: <#
10: new ProcereMappingTemplate(this.Host.ResolvePath("UserModel.edmx"),".","EFExtensions").Render();
11: #>
四、看看生成出來的.emdx
通過上面創建的TT模板(你指定的資料庫中一定要存在具有相應映射關系的存儲過程),新的.edmx模型文件會作為該tt文件的依賴文件被生成出來。而這個新生成的.edmx具有存儲過程映射信息。具體來說,下面是原始的.edmx文件(只保留元數據節點)。
1: <?xml version="1.0" encoding="utf-8"?>
2: <edmx:Edmx Version="2.0" xmlns:edmx="http://schemas.microsoft.com/ado/2008/10/edmx">
3: <!-- EF Runtime content -->
4: <edmx:Runtime>
5: <!-- SSDL content -->
6: <edmx:StorageModels>
7: <Schema Namespace="Artech.UserModel.Store" Alias="Self" Provider="System.Data.SqlClient" ProviderManifestToken="2008" xmlns:store="http://schemas.microsoft.com/ado/2007/12/edm/EntityStoreSchemaGenerator" xmlns="http://schemas.microsoft.com/ado/2009/02/edm/ssdl">
8: <EntityContainer Name="ArtechUserModelStoreContainer">
9: <EntitySet Name="T_USER" EntityType="Artech.UserModel.Store.T_USER" store:Type="Tables" Schema="dbo" />
10: </EntityContainer>
11: <EntityType Name="T_USER">
12: <Key>
13: <PropertyRef Name="USER_ID" />
14: </Key>
15: <Property Name="USER_ID" Type="varchar" Nullable="false" MaxLength="50" />
16: <Property Name="USER_NAME" Type="nvarchar" Nullable="false" MaxLength="50" />
17: </EntityType>
18: </Schema>
19: </edmx:StorageModels>
20: <!-- CSDL content -->
21: <edmx:ConceptualModels>
22: <Schema Namespace="Artech.UserModel" Alias="Self" xmlns:annotation="http://schemas.microsoft.com/ado/2009/02/edm/annotation" xmlns="http://schemas.microsoft.com/ado/2008/09/edm">
23: <EntityContainer Name="EFExtensionsEntities" annotation:LazyLoadingEnabled="true">
24: <EntitySet Name="Users" EntityType="Artech.UserModel.User" />
25: </EntityContainer>
26: <EntityType Name="User">
27: <Key>
28: <PropertyRef Name="ID" />
29: </Key>
30: <Property Name="ID" Type="String" Nullable="false" MaxLength="50" Unicode="false" FixedLength="false" />
31: <Property Name="Name" Type="String" Nullable="false" MaxLength="50" Unicode="true" FixedLength="false" />
32: </EntityType>
33: </Schema>
34: </edmx:ConceptualModels>
35: <!-- C-S mapping content -->
36: <edmx:Mappings>
37: <Mapping Space="C-S" xmlns="http://schemas.microsoft.com/ado/2008/09/mapping/cs">
38: <EntityContainerMapping StorageEntityContainer="ArtechUserModelStoreContainer" CdmEntityContainer="EFExtensionsEntities">
39: <EntitySetMapping Name="Users">
40: <EntityTypeMapping TypeName="Artech.UserModel.User">
41: <MappingFragment StoreEntitySet="T_USER">
42: <ScalarProperty Name="ID" ColumnName="USER_ID" />
43: <ScalarProperty Name="Name" ColumnName="USER_NAME" />
44: </MappingFragment>
45: </EntityTypeMapping>
46: </EntitySetMapping>
47: </EntityContainerMapping>
48: </Mapping>
49: </edmx:Mappings>
50: </edmx:Runtime>
51: </edmx:Edmx>
這是新生成的.edmx文件中的XML。
㈡ 計算機設備名稱英語詞彙
計算機設備名稱英語詞彙
計算機可以由個人需要,組合多種設備。下面是我分享的計算機設備英語名稱,希望能對大家有所幫助!
磁碟
AAT(Average access time,平均存取時間)
ABS(Auto Balance System,自動平衡系統)
ASMO(Advanced Storage Magneto-Optical,增強形光學存儲器)
AST(Average Seek time,平均尋道時間)
ATA(AT Attachment,AT擴展型)
ATOMM(Advanced super Thin-layer and high-Output Metal Media,增強形超薄高速金屬媒體)
bps(bit per second,位/秒)
CAM(Common Access Model,公共存取模型)
CSS(Common Command Set,通用指令集)
DMA(Direct Memory Access,直接內存存取)
DVD(Digital Video Disk,數字視頻光碟)
EIDE(enhanced Integrated Drive Electronics,增強形電子集成驅動器)
FAT(File Allocation Tables,文件分配表)
FDBM(Fluid dynamic bearing motors,液態軸承馬達)
FDC(Floppy Disk Controller,軟盤驅動器控制裝置)
FDD(Floppy Disk Driver,軟盤驅動器)
GMR(giant magnetoresistive,巨型磁阻)
HDA(head disk assembly,磁頭集合)
HiFD(high-capacity floppy disk,高容量軟盤)
IDE(Integrated Drive Electronics,電子集成驅動器)
LBA(Logical Block Addressing,邏輯塊定址)
MBR(Master Boot Record,主引導記錄)
MTBF(Mean Time Before Failure,平均故障時間)
PIO(Programmed Input Output,可編程輸入輸出模式)
PRML(Partial Response Maximum Likelihood,最大可能部分反應,用於提高磁碟讀寫傳輸率)
RPM(Rotation Per Minute,轉/分)
RSD:(Removable Storage Device移動式存儲設備)
SCSI(Small Computer System Interface,小型計算機系統介面)
SCMA:(SCSI Configured Auto Magically,SCSI自動配置)
S.M.A.R.T.(Self-Monitoring, Analysis and Reporting Technology,自動監測、分析和報告技術)
SPS(Shock Protection System,抗震保護系統)
STA(SCSI Trade Association,SCSI同業公會)
Ultra DMA(Ultra Direct Memory Access,超高速直接內存存取)
LVD(Low Voltage Differential)
Seagate硬碟技術DiscWizard(磁碟控制軟體)
DST(Drive Self Test,磁碟自檢程序)
SeaShield(防靜電防撞擊外殼)
RAM & ROM
ABP: (Address Bit Permuting,地址位序列改變)
ATC(Access Time from Clock,時鍾存取時間)
BSRAM(Burst pipelined synchronous static RAM,突發式管道同步靜態存儲器)
CAS(Column Address Strobe,列地址控制器)
CCT(Clock Cycle Time,時鍾周期)
DB: (Deep Buffer深度緩沖)
DDR SDRAM(Double Date Rate,雙數據率SDRAM)
DIL(al-in-line)
DIMM(Dual In-line Memory Moles,雙重內嵌式內存模塊)
DRAM(Dynamic Random Access Memory,動態隨機存儲器)
DRDRAM(Direct RAMbus DRAM,直接RAMbus內存)
ECC(Error Checking and Correction,錯誤檢查修正)
EEPROM(Electrically Erasable Programmable ROM,電擦寫可編程只讀存儲器)
FM: (Flash Memory快閃記憶體)
FMD ROM (Fluorescent Material Read Only Memory,熒光質只讀存儲器)
PIROM:(Processor Information ROM,處理器信息ROM)
PLEDM: Phase-state Low Electron(hole)-number Drive Memory QBM(Quad Band Memory,四倍邊帶內存)
RAC(Rambus Asic Cell,Rambus集成電路單元)
RAS(Row Address Strobe,行地址控制器)
RDRAM(Rambus Direct RAM,直接型RambusRAM)
RIMM(RAMBUS In-line Memory Moles,RAMBUS內嵌式內存模塊)
SDR SDRAM(Single Date Rate,單數據率SDRAM)
SGRAM(synchronous graphics RAM,同步圖形隨機儲存器)
SO-DIMM(Small Outline Dual In-line Memory Moles,小型雙重內嵌式內存模塊)
SPD(Serial Presence Detect,串列存在檢查)
SRAM(Static Random Access Memory,靜態隨機存儲器)
SSTL-2(Stub Series Terminated Logic-2)
TSOPs(thin small outline packages,超小型封裝)
USWV(Uncacheable, Speculative, Write-Combining非緩沖隨機混合寫入)
VCMA(Virtual Channel Memory architecture,虛擬通道內存結構)
;