2013-01-10 13 views
31

私はMySQLデータベースからEF4モデルを生成しました。私はStoredProceduresとTablesの両方を含んでいます。EntityFrameworkでストアドプロシージャを呼び出す方法

私はEFに対して通常のinstert/update/fetch/delete操作を行う方法を知っていますが、私のStoredProceduresは見つかりません。編集1

using (Entities context = new Entities()) 
{ 
    context.MyStoreadProcedure(Parameters); 
} 

これは私が望んでいたものだった

これは、それがEFせずに見てどのようである:

sqlStr = "CALL updateGame(?,?,?,?,?,?,?)"; 

commandObj = new OdbcCommand(sqlStr, mainConnection); 
commandObj.Parameters.Add("@id,", OdbcType.Int).Value = inGame.id; 
commandObj.Parameters.Add("@name", OdbcType.VarChar, 255).Value = inGame.name; 
commandObj.Parameters.Add("@description", OdbcType.Text).Value = ""; //inGame.description; 
commandObj.Parameters.Add("@yearPublished", OdbcType.DateTime).Value = inGame.yearPublished; 
commandObj.Parameters.Add("@minPlayers", OdbcType.Int).Value = inGame.minPlayers; 
commandObj.Parameters.Add("@maxPlayers", OdbcType.Int).Value = inGame.maxPlayers; 
commandObj.Parameters.Add("@playingTime", OdbcType.VarChar, 127).Value = inGame.playingTime;  

return Convert.ToInt32(executeScaler(commandObj)); 

PS。必要であれば、私はEFのバージョンを変更することができます

編集1:

CREATE DEFINER=`106228`@`%` PROCEDURE `updateGame`(
    inId INT, 
    inName VARCHAR(255), 
    inDescription TEXT, 
    inYearPublished DATETIME, 
    inMinPlayers INT, 
    inMaxPlayers INT, 
    inPlayingTime VARCHAR(127) 
) 

答えて

0

これは私が最近2008 SQLデータベースを持っている私のデータ視覚化アプリケーションのためにやったことです。ジュリーによって

public string GetRunLogFilterSQLString(string procedureName, RunLogFilter filter) 
     { 
      return string.Format("EXEC {0} {1},{2}, {3}, {4}", procedureName, filter.SystemFullName == null ? "null" : "\'" + filter.SystemFullName + "\'", filter.MinimumDate == null ? "null" : "\'" + filter.MinimumDate.Value + "\'", filter.MaximumDate == null ? "null" : "\'" + filter.MaximumDate.Value + "\'", +filter.Reconciled == null ? "null" : "\'" + filter.Reconciled + "\'"); 

     } 
+0

私はそれを得ることができません、なぜ私はSP名をハードコードする必要がありますか?モデルを生成するときに追加しましたか? Contextオブジェクトのどこかにメソッドとして存在するだけではないでしょうか? – Ivy

-1

優れた記事(および関連ビデオ)を読む:

public List<CumulativeInstrumentsDataRow> GetCumulativeInstrumentLogs(RunLogFilter filter) 
    { 
     EFDbContext db = new EFDbContext(); 
     if (filter.SystemFullName == string.Empty) 
     { 
      filter.SystemFullName = null; 
     } 
     if (filter.Reconciled == null) 
     { 
      filter.Reconciled = 1; 
     } 
     string sql = GetRunLogFilterSQLString("[dbo].[rm_sp_GetCumulativeInstrumentLogs]", filter); 
     return db.Database.SqlQuery<CumulativeInstrumentsDataRow>(sql).ToList(); 
    } 

そして、私の場合は、いくつかの書式設定のために、この拡張メソッドは、この例では、私は、ストアドプロシージャから返されたリストが供給していますラーマン(プログラミングエンティティフレームワークの作者)

Stored Procedures in the Entity Framework

+1

単純なStoredProcedureを実行するだけのテキストがたくさんありますが、EFがSPを多少忘れてしまったような気がしますか?コンテキストオブジェクトにメソッドとしてのthayがないのはなぜですか? Thayはモデル生成時に追加されましたか? – Ivy

+0

これは仕様です。コンテキストオブジェクトは単純に 'ObjectSet 'です。そして、SPで遊ぶことは 'IQueryable'で遊ぶのと同じではありません – Tilak

+0

これがリンク専用のポストを止める理由です。このリンクは今Entity Frameworkのホームページに移動します。 – saluce

57

一つの方法は、DbContextオフDatabaseプロパティを使用することです:

SqlParameter param1 = new SqlParameter("@firstName", "Frank"); 
SqlParameter param2 = new SqlParameter("@lastName", "Borland"); 
context.Database.ExecuteSqlCommand("sp_MyStoredProc @firstName, @lastName", 
           param1, param2); 

EF5はこれをサポートしています。

+0

私はそれを取得しない、なぜ私はSP名をハードコードする必要がありますか?モデルを生成するときに追加しましたか? Contextオブジェクトのどこかにメソッドとして存在するだけではないでしょうか? – Ivy

+1

これはモデルにリンクしておらず、_raw_アクセスが必要な場合にこれを行う方法です) –

+1

これは、ストアドプロシージャを非クエリとして実行するだけです。それは返されたテーブルを読み取ることができません –

4

モデルにストアドプロシージャをインポートしたら、(モデルブラウザのContext.Store/Stored Proceduresセクションで)右クリックし、Add Function Importをクリックします。結果として複雑なタイプが必要な場合は、そこに作成することができます。

+0

これを試してみましたが、パラメータを持つメソッドを生成しませんか?パラメータをどのようにパッティングするかわからない – Ivy

+1

プロシージャにパラメータがある場合、プロシージャにパラメータが追加されます。 – user1908061

+0

それはありませんか? – Ivy

8

SqlQuery関数を使用し、結果をマッピングするエンティティを指定しています。

これを実行するように私は例を送る:

var oficio= new SqlParameter 
{ 
    ParameterName = "pOficio", 
    Value = "0001" 
}; 

using (var dc = new PCMContext()) 
{ 
    return dc.Database 
      .SqlQuery<ProyectoReporte>("exec SP_GET_REPORTE @pOficio", 
             oficio) 
      .ToList(); 
} 
+0

クエリによって返された結果テーブルを表す 'ProyectoReporte'クラスを宣言する必要があります –

0

は、基本的にはあなただけのストアドプロシージャのマッピングを使用してエンティティに手続きをマップする必要があります。

一度マップされると、EFでアイテムを追加するための通常の方法が使用され、代わりにストアドプロシージャが使用されます。

ご覧ください:This Linkウォークスルー。 結果はOPの元の要求は、このようなストアドプロシージャを呼び出しできるようにするには、最大基づきので(実際にあなたのストアドプロシージャを使用します)

using (var ctx = new SchoolDBEntities()) 
     { 
      Student stud = new Student(); 
      stud.StudentName = "New sp student"; 
      stud.StandardId = 262; 

      ctx.Students.Add(stud); 
      ctx.SaveChanges(); 
     } 
1

のようなエンティティを追加していく予定...

using (Entities context = new Entities()) 
{ 
    context.MyStoreadProcedure(Parameters); 
} 

Mindless passengerは....

using (testentities te = new testentities()) 
{ 
    //------------------------------------------------------------- 
    // Simple stored proc 
    //------------------------------------------------------------- 
    var parms1 = new testone() { inparm = "abcd" }; 
    var results1 = te.CallStoredProc<testone>(te.testoneproc, parms1); 
    var r1 = results1.ToList<TestOneResultSet>(); 
} 

をあなたは、このようなエンティティフレームワークからストアドプロシージャを呼び出すことができますプロジェクトを持っている...と私はstored procedure frameworkhere)に取り組んでいましたこれら2つのアプローチのいずれかが何か良いであれば、あなたは

[TestClass] 
public class TenantDataBasedTests : BaseIntegrationTest 
{ 
    [TestMethod] 
    public void GetTenantForName_ReturnsOneRecord() 
    { 
     // ARRANGE 
     const int expectedCount = 1; 
     const string expectedName = "Me"; 

     // Build the paraemeters object 
     var parameters = new GetTenantForTenantNameParameters 
     { 
      TenantName = expectedName 
     }; 

     // get an instance of the stored procedure passing the parameters 
     var procedure = new GetTenantForTenantNameProcedure(parameters); 

     // Initialise the procedure name and schema from procedure attributes 
     procedure.InitializeFromAttributes(); 

     // Add some tenants to context so we have something for the procedure to return! 
     AddTenentsToContext(Context); 

     // ACT 
     // Get the results by calling the stored procedure from the context extention method 
     var results = Context.ExecuteStoredProcedure(procedure); 

     // ASSERT 
     Assert.AreEqual(expectedCount, results.Count); 
    } 
} 

internal class GetTenantForTenantNameParameters 
{ 
    [Name("TenantName")] 
    [Size(100)] 
    [ParameterDbType(SqlDbType.VarChar)] 
    public string TenantName { get; set; } 
} 

[Schema("app")] 
[Name("Tenant_GetForTenantName")] 
internal class GetTenantForTenantNameProcedure 
    : StoredProcedureBase<TenantResultRow, GetTenantForTenantNameParameters> 
{ 
    public GetTenantForTenantNameProcedure(
     GetTenantForTenantNameParameters parameters) 
     : base(parameters) 
    { 
    } 
} 

...以下のとおり私のテストのいずれかの方法でのように呼び出すことができますか?

関連する問題