當前位置:首頁 » 存儲配置 » entityframework存儲過程

entityframework存儲過程

發布時間: 2022-05-20 20:07:51

㈠ ado.net entity framework 調用存儲過程

查詢存儲過程的寫法:

BlogContext db =newBlogContext();
sqlParameter[] parms =newSqlParameter[1];
parms[0]=newSqlParameter("@ID",1);
var result = db.Articles.SqlQuery("exec P_GetArticleByID @ID", parms);
returnView(result);

㈡ Entity Framework怎麼調用存儲過程

SqlParameter[] parms = new SqlParameter[2];
SqlParameter id = new SqlParameter("ID", "11a44466-6d9c-4c7e-b9e4-5a1369061119");
id.SqlDbType=SqlDbType.NVarChar;
id.Size = 128;
parms[0] = id;
var outParam = new SqlParameter();
outParam.ParameterName = "Name";
outParam.SqlDbType = SqlDbType.VarChar;
outParam.Size = 64; //必須填寫正確,否則會有這種異常:{"String[1]: the Size property has an invalid size of 0."}
outParam.Direction = ParameterDirection.Output;
parms[1]=outParam;

//當有這樣異常時,"... A member of the type ... does not have a corresponding column in the data reader with the same name"
//是存儲過程返回的欄位名與對應Model的屬性名對不上, 解決加法是在存儲過程中取別名與Model的屬性同名
var result = db.Database.SqlQuery<Category>("P_GetCategoryByID @ID,@Name output", parms);

string title = outParam.Value as string;

㈢ 在 MVC+Entity Framework 的開發中調用存儲過程,出現奇怪的問題

改過model沒,改了的話要做資料庫遷移

㈣ entity framework 使用存儲過程刪除數據後,還用再使用SaveChanges()保存嗎

執行存儲過程後是直接執行了SQL語句 但是如果不適用 SaveChanges()保存的話 EF在內存維護的數據會沒有改變 如果不注意一下的話 可能會引起讀取的是舊數據 也就是讀取的是內存中的數據。 EF 有些方法是會先讀取內存中維護的數據如果沒有才會從資料庫中執行SQL語句讀取資料庫中的數據的。 使用 SaveChanges() 方法是非常重要的 當然最安全的就是執行方法結束後 立即SaveChanges() 但要是操作的方法涉及到多個執行語句 那麼就建議全部執行完成後保存

㈤ 在Entity Framework中使用存儲過程(四):如何為Delete存儲過程參數賦上Current值

四、為Delete存儲過程參數賦上Current值,如何做得到?一、EF存儲過程參數賦值的版本策略和傳統的基於DataSet的ADO.NET類似,EF的核心功能之一就是「狀態追蹤(State Tacking)」。這中間實際上又涉及到兩個方面:通過狀態決定數據更新的類型(Insert、Update和Delete);以及同時保存不同版本的屬性值(Current值和Original值)。版本策略主要是針對Update操作設計的,一般來講組成Where條件的為Original值,而更新的值為Current值。正是因為只有Update操作才需要顯式指定映射的是實體屬性值的版本(Current/Original),所以在進行實體/存儲過程映射的時候,只有Update存儲過程才可以選擇「是否採用原始值(Use Original Value)」。Insert和Delete存儲過程默認的版本為Current和Original。反映在VS的.edmx模型設計器上就是:只有Update存儲過程的參數映射才具有「Use Original Value」這個復選框。二、Delete存儲參數隊應的就一定是Original值嗎?粗略地想想,EF這樣設計也無可厚非:Insert存儲過程用於添加一條全新的記錄,自然應該採用當前值;而Delete存儲過程用於刪除一條現有的記錄,刪除操作的篩選條件自然應該使用原始值。但是,我們忽略掉一點:Delete存儲過程一定非得執行刪除操作嗎?如果我進行「邏輯刪除」,實際上進行的是Update操作。關於邏輯刪除的實現,可以參閱我上一篇文章《邏輯刪除的實現與自增長列值返回》。如果你看了我提到的這篇文章,你可能會問,即使在文中介紹的關於「邏輯刪除」的場景中,也沒有使用當前值得要求呀。是的,上一篇文章提到的邏輯刪除確實也只需要傳入實體屬性的原始值作為Delete存儲過程的參數,現在我們就舉一個這樣的例子。通過是使用T_CONTACT這張簡單不過的表,同樣是採用邏輯刪除。不過現在有這樣的一個要求,對於條存儲在的記錄,我們需要記錄最後修改者是誰。對於一條被邏輯刪除掉的記錄,這個最後修改者就是刪除掉該條記錄的人。這是一個很常見的需求,為此我們可以直接在T_CONTACT的數據表中添加一個新的欄位:LAST_UPDATED_BY,創建該表的DDL定義如下: 1:CREATETABLE [T_CONTACT] 2: ( 3: [ID] [INT] IDENTITY(1,1) PRIMARYKEY, 4: [NAME] [NVARCHAR](50) NOTNULL, 5: [IS_DELETED] [BIT] NOTNULL, 6: [LAST_UPDATED_BY] [NVARCHAR](50) NOTNULL 7: )那麼對於Delete存儲過程,除了指定需要刪除的記錄的主鍵之外,還需要將當前用戶名作為參數作為傳進來。這樣的一個存儲過程具有如下的定義 1:CREATEPROCEDURE [dbo].[P_CONTACT_D] 2: ( 3: @p_id INT, 4: @user_name NVARCHAR(50) 5: ) 6:AS 7:BEGIN 8:UPDATE T_CONTACT 9:SET IS_DELETED = 1, 10: LAST_UPDATED_BY = @user_name 11:WHERE ID = @p_id 12:END在實際操作場景下,我們需要先獲取一條現有的Contact記錄,然後將其標記為刪除。然後Delete存儲過程被執行,並且採用預先定義好的實體屬性/參數的映射關系來對存儲過程的參數進行賦值。但是,由於Delete存儲過程默認使用的是實體對象的初始值,即使你在刪除之前為Contact對象的LastUpdatedBy屬性設置了新的值,該值也不可能傳入到存儲過程中去。三、如果直接修改.edmx模型的XML呢?由於Delete過程只能接受實體的映射屬性的初始值作為參數,導致我們無法指定一個新的值作為參數。我想有人會有這樣的疑問:VS提供的設計器不能提供你指定Delete存儲過程參數版本的功能,你是否可以直接修改.edmx文件的XML呢?我們不妨來嘗試一下:在整個XML中,實體的CUD存儲過程映射對應如下一段XML片段,我們可以看到,只有UpdateFunction中的參數映射節點才有Version屬性(而且這是一個必需的屬性),用於指定參數定義的是Original值還是Current值。 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18:那些現在我們將DeleteFunction的user_name參數的映射節點人為地加上Version=「Current」屬性設置。 1: 2: 3: 4:但是當你進行編譯的時候,會出現如下的錯誤,明確告訴你:「This function mapping can only contain bindings to 'original' property versions.」四、為Delete存儲過程參數賦上Current值,如何做得到?從上面的介紹我們不難發現,Delete存儲過程不能接受基於當前值得參數映射,並不僅僅是設計器不支持,EF本來就是這樣設計的。在這種情況下要實現我們的要求,只有一個辦法:將當前值轉化成初始值值,這樣的轉變通過調用ObjectContext的AcceptAllChanges方法可以實現。具體來說,對於需要刪除的實體,現設定LastUpdatedBy屬性,然後調用AcceptAllChanges方法,然後再調用ObjectStateManager的ChangeObjectState方法將狀態設置為Deleted。最終通過調用SaveChanges方法提交更新,具體的代碼如下: 1:staticvoid Main(string[] args) 2: { 3:using (EFExtensionsEntities context = new EFExtensionsEntities()) 4: { 5: Contact contact = new Contact { Name = "Foo", LastUpdatedBy = "Bar" }; 6: context.Contacts.AddObject(contact); 7: context.SaveChanges(); 8: Console.WriteLine("{0}: {1}", contact.ID, contact.Name); 9: 10: contact.LastUpdatedBy = "Baz"; 11: context.AcceptAllChanges(); 12: context.ObjectStateManager.ChangeObjectState(contact, EntityState.Deleted); 13: context.SaveChanges(); 14: } 15: }執行上面的程序後,你會在資料庫中發現為刪除對象指定的LastUpdatedBy屬性「Baz」,而不是初始值「Bar」最終反映在資料庫中。雖然通過「曲線救國」我們可以實現為實體映射的Delete存儲過程指定一個「新值」作為某個參數的值,但是這樣的做法總覺得不怎麼優雅。所以,我個人覺得這是EF一個值得改進的地方,讓Delete存儲過程和Update一樣,也可以指定不同的版本。在Entity Framework中使用存儲過程(一):實現存儲過程的自動映射在Entity Framework中使用存儲過程(二):具有繼承關系實體的存儲過程如何定義?在Entity Framework中使用存儲過程(三):邏輯刪除的實現與自增長列值返回

㈥ net entity framework 存儲過程 能直接返回 datatable嗎

似乎沒有內置的函數,不過既然你想用datatable,直接用sqldataadapter不就好了?

㈦ Entity Framework 5.0 調用存儲過程 返回值為什麼是int類型

存儲過程的返回值類型固定為int類型,不支持其它類型,函數才可以返回多樣化類型。如果你要通過存儲過程傳遞數據出來,請使用輸出型參數。
這是SQL的基礎知識,和C#無關。

㈧ 在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。

熱點內容
壓縮殼脫殼機 發布:2024-09-21 03:14:33 瀏覽:93
熱血街籃為什麼是伺服器維護中 發布:2024-09-21 03:08:19 瀏覽:937
喇叭怎麼配置功放 發布:2024-09-21 03:06:50 瀏覽:751
為什麼安卓的內存沒有蘋果的內存 發布:2024-09-21 03:06:50 瀏覽:231
swift解壓 發布:2024-09-21 02:31:47 瀏覽:704
移動中心怎麼配置安卓系統 發布:2024-09-21 02:27:16 瀏覽:606
安卓手機舊版app怎麼下載 發布:2024-09-21 02:12:35 瀏覽:799
方舟知道ip怎麼加入伺服器 發布:2024-09-21 02:12:14 瀏覽:791
像素工廠如何加入遠程伺服器 發布:2024-09-21 02:11:00 瀏覽:824
手機服務密碼怎麼獲取 發布:2024-09-21 02:10:55 瀏覽:253