7

私のデータベースにSPがあります。 EF4.1では、DbContext APIを使用します。Entity Framework EF4.1 - ストアドプロシージャが「コンテナ内に見つかりません」

データモデルから関数をインポートした後、ストアドプロシージャへの参照は開発環境で正常に動作します。しかし、サーバーに公開すると、次のようなメッセージが表示されて失敗します。FunctionImport 'SqlSearch'がコンテナ 'TallyJ2Entities'に見つかりませんでした。他のすべてのデータアクセスは正常に動作しています。

生産時には、EF4構成のいくつかの側面が忘れられているようです。

データベースは同一で、両方のサーバーがSQL 2008(ローカルはExpress SP1 10.50.2500、ホストはExpress RTM 10.50.1600)です。

私は、EDMXエディタを本番データベースに直接指摘し、更新しました。その結果は開発でうまくいきましたが、サーバー上で同じように失敗します。

他のよく似た質問here助けてください。他の誰かが同様の問題を抱えているようです。enter link description here

提案がありますか?

更新:私は、デバッグモードでホストを展開すると問題が解消されることがわかりました。 、それを

((IObjectContextAdapter)this).ObjectContext.MetadataWorkspace 
var findFunction = metadataWorkspace.GetItems(DataSpace.SSpace) 
      .SelectMany(gi => gi.MetadataProperties) 
      .Where(m=> Equals(m.Value, "SqlSearch")) 
      .Select(m => "Found {0}".FilledWith(m.Value)) 
      .FirstOrDefault(); 

私はfindFunction結果をログに記録する場合、開発中ながら、それは、(リリースモードで)サーバがそれを見つけられませんでしたことが判明:

は私のDbContext派生クラス内では、私はこのコードを置きます見つかった。

+0

このことに関して多くの疑問があるようです:http://stackoverflow.com/a/3501174/2942 http://stackoverflow.com/questions/4892926/entity-framework-4-pocos-stored-procedure- error-the-functionimport-could-not – friism

+0

ありがとうございます。しかし、他のアイディアのどれも私のために働いていませんでした。 –

答えて

18

EF 4.1以上を使用している場合は、Context.csファイルの "ObjectParameter"を "SqlParameter"に変更し、 "ExecuteFunction"を "ExecuteStoreQuery"に変更します。

「ExecuteStoreQuery」メソッドでは、ストアドプロシージャの前にパラメータ名を追加することも想定されています。以下のスニペット検索:あなたのコードを生成するためのテンプレートを使用している場合

var param1Parameter = param1 != null ? 
new SqlParameter("param1", param1) : 
new SqlParameter("param1", typeof(string)); 

var param2Parameter = param2 != null ? 
new SqlParameter("param2", param2) : 
new SqlParameter("param2", typeof(int)); 

return ((IObjectContextAdapter)this).ObjectContext.ExecuteStoreQuery<sp_TestSproc_Result>("sp_TestSproc @param1, @param2", param1Parameter, param2Parameter); 

を、あなたにも便利以下のスニペットを見つけるかもしれません。私。私は標準の "Fluent TT"ジェネレータをEF 4.3に合わせて修正しました:

void WriteFunctionImport(EdmFunction edmFunction, bool includeMergeOption) 
    { 
     var parameters = FunctionImportParameter.Create(edmFunction.Parameters, Code, EFTools); 
     var paramList = String.Join(", ", parameters.Select(p => p.FunctionParameterType + " " + p.FunctionParameterName).ToArray()); 
     var returnType = edmFunction.ReturnParameter == null ? null : EFTools.GetElementType(edmFunction.ReturnParameter.TypeUsage); 
     var processedReturn = returnType == null ? "int" : "ObjectResult<" + MultiSchemaEscape(returnType) + ">"; 

     if (includeMergeOption) 
     { 
      paramList = Code.StringAfter(paramList, ", ") + "MergeOption mergeOption"; 
     } 
    #> 

     <#=AccessibilityAndVirtual(Accessibility.ForMethod(edmFunction))#> <#=processedReturn#> <#=Code.Escape(edmFunction)#>(<#=paramList#>) 
     { 
    <#+ 
      if(returnType != null && (returnType.EdmType.BuiltInTypeKind == BuiltInTypeKind.EntityType || 
             returnType.EdmType.BuiltInTypeKind == BuiltInTypeKind.ComplexType)) 
      { 
    #> 
      ((IObjectContextAdapter)this).ObjectContext.MetadataWorkspace.LoadFromAssembly(typeof(<#=MultiSchemaEscape(returnType)#>).Assembly); 

    <#+ 
      } 

      foreach (var parameter in parameters.Where(p => p.NeedsLocalVariable)) 
      { 
       var isNotNull = parameter.IsNullableOfT ? parameter.FunctionParameterName + ".HasValue" : parameter.FunctionParameterName + " != null"; 
       var notNullInit = "new SqlParameter(\"" + parameter.EsqlParameterName + "\", " + parameter.FunctionParameterName + ")"; 
       var nullInit = "new SqlParameter(\"" + parameter.EsqlParameterName + "\", typeof(" + parameter.RawClrTypeName + "))"; 
    #> 
      var <#=parameter.LocalVariableName#> = <#=isNotNull#> ? 
       <#=notNullInit#> : 
       <#=nullInit#>; 

    <#+ 
      } 

      var genericArg = returnType == null ? "" : "<" + MultiSchemaEscape(returnType) + ">"; 
      var callParams = Code.StringBefore(", ", String.Join(", ", parameters.Select(p => p.ExecuteParameterName).ToArray())); 
      var spParams = Code.StringBefore("@", String.Join(", @", parameters.Select(p => p.EsqlParameterName).ToArray())); 

      if (includeMergeOption) 
      { 
       callParams = ", mergeOption" + callParams; 
      } 
    #> 
      return ((IObjectContextAdapter)this).ObjectContext.ExecuteStoreQuery<#=genericArg#>("<#=edmFunction.Name#> <#=spParams#>" 
         <#=callParams#>); 
     } 
    <#+ 
     if(!includeMergeOption && returnType != null && returnType.EdmType.BuiltInTypeKind == BuiltInTypeKind.EntityType) 
     { 
      WriteFunctionImport(edmFunction, true); 
     } 
    } 
+0

ありがとう...私は次の1〜2週間でこれを試してみます。うまくいけば、デバッグモードから抜け出すことができます! –

+1

これは私のために働いた! – tclark333

+0

完璧、ありがとう!私がこれを自分で見つけ出すのにどれくらいの時間がかかったのか分かりません! – Marc

4

これは接続文字列が間違っていることが原因であることがわかりました。それはmymodelという、これはあなたの.edmxモデルファイルの名前に対応する必要があります言う

<connectionStrings> 
    <add name="MyModel_Entities" connectionString="metadata=res://*/Models.MyModel.csdl|res://*/Models.MyModel.ssdl|res://*/Models.MyModel.msl;provider=System.Data.SqlClient;provider connection string=&quot;data source=192.168.1.200;initial catalog=MyDb_Live;integrated security=True;MultipleActiveResultSets=True;App=EntityFramework&quot;" providerName="System.Data.EntityClient" /> 
</connectionStrings> 

EFは、次のようになり、接続文字列を必要とします。

あなたはどこか別の場所かられたconnectionStringをコピーした場合、それは次のようになります。

<add name="MyModel_Entities" connectionString="Data Source=.;Initial Catalog=MyDb_Live;Integrated Security=SSPI;MultipleActiveResultSets=true" providerName="System.Data.SqlClient" /> 

ノートのconnectionStringsの終わりにproviderNameでで特に違い。

NB私たちはEF 6.1を使用していますが、これは以前のバージョンにも当てはまります。 接続文字列を修正すると、T4テンプレートで生成されたコードを引き続き使用できることがわかりました。 ObjectParameterをSqlParameterに、ExecuteFunctionをExecuteStoreQueryに切り替える必要はありません。

+0

私は同意します...接続文字列形式はEFにとって重要です。それを強調していただきありがとうございます。 –

0

私は接続文字列が問題ではないと思います。私の場合、ストアプロシージャを呼び出すことができませんが、私のDBにデータを書き込めます。私たちの接続が適切であることを意味します。

関連する問題