2017-09-13 13 views
0

GetScalarメソッドを作成しようとしています。レガシーシステムでは多くのDataTableを使用しています。私はそれらをEFに変換しています。Entity Framework - スカラーを取得する

ここに目標があります。これは、ストアドプロシージャの名前とパラメータを取得し、結果セットの最初の行、最初の列を返す単純なメソッドです。

public object GetScalar(string command, CommandType type = CommandType.StoredProcedure, List<SqlParameter> parameterList = null) 
    { 
     try 
     { 
      using (var cnn = new SqlConnection(ConnectionString)) 
      { 
       using (var cmd = new SqlCommand(command, cnn)) 
       { 
        cmd.CommandType = type; 

        if (parameterList != null) 
        { 
         foreach (var p in parameterList) 
         { 
          cmd.Parameters.Add(p); 
         } 
        } 

        cmd.Connection.Open(); 
        object obj = cmd.ExecuteScalar(); 
        cmd.Connection.Close(); 
        cmd.Parameters.Clear(); 
        return obj; 
       } 
      } 
     } 
     catch (Exception ex) 
     { 
      Logging.LogError(ex, "MSSqlUtility.GetScalar"); 
      return -1; 
     } 
    } 

私はEFで同様の方法を使いたいと思っています。これまで私がこれまで持っていたことはありますが、これは最初の列だけでなくすべての列を返します。

protected T SelectScalar<T>(string inStoredProcedure, ICollection<SqlParameter> inParameters = null) 
    { 
     T result = default(T); 
     if (inParameters != null && inParameters.Count > 0) 
     { 
      string paramNames = string.Join(",", inParameters.Select(parameter => parameter.ParameterName).ToList()); 
      string sqlString = inStoredProcedure + " " + paramNames; 
      object[] paramValues = inParameters.Cast<object>().ToArray();    
      result = Database.SqlQuery<T>(sqlString, paramValues).FirstOrDefault(); 
     } 
     else 
     { 
      result = Database.SqlQuery<T>(inStoredProcedure).FirstOrDefault(); 
     } 

     return result; 
} 

使用例。これは文字列オブジェクト "John Doe"を返します。 - 私たちは、他のコンテキストで両方の列を必要とする

SELECT 
    FirstName + ' ' + Last Name 
,EmployeeID 
FROM Users 

オプションではありませんストアドプロシージャを変更する:

public string GetUserName(string employeeID) 
    { 
     if (string.IsNullOrWhiteSpace(employeeID)) 
     { 
      return string.Empty; 
     } 

     var parameters = new Collection<SqlParameter>();    
     parameters.Add(StoredProcedureParameterBuilder.StringParam("@EmployeeID", employeeID, 20)); 
     return this.SelectScalar<string>("dbo.GetUserName", parameters).Trim(); 
    } 

SQLクエリは次のようになります。現在のコードでは、という名前とIDという名前が返されます。私は最初の列、最初の行だけを取得したいと思います。

+1

このメソッドの使用方法とその結果の例を追加できますか? –

答えて

0

もう少し手作業で作業する必要がありました。誰かがもっと良い解決策を持っていれば、私はすべて耳にしますが、これは私のユースケースではうまくいきます:

/// <summary> 
    /// Selects the first item in the query's result. 
    /// </summary> 
    /// <typeparam name="T"></typeparam> 
    /// <param name="inStoredProcedure">The in stored procedure.</param> 
    /// <param name="inParameters">The in parameters.</param> 
    /// <returns>The first object in the specified type T.</returns> 
    protected T SelectScalar<T>(string inStoredProcedure, ICollection<SqlParameter> inParameters = null) 
    {    
     using (System.Data.IDbCommand command = Database.Connection.CreateCommand()) 
     { 
      try 
      {     
       command.CommandText = inStoredProcedure; 
       command.CommandTimeout = command.Connection.ConnectionTimeout; 

       if(inParameters != null && inParameters.Count > 0) 
       { 
        string paramNames = string.Join(",", inParameters.Select(parameter => parameter.ParameterName).ToList()); 
        command.CommandText += " " + paramNames; 
        foreach (var param in inParameters) 
        { 
         command.Parameters.Add(param); 
        } 
       } 

       Database.Connection.Open(); 
       return (T)command.ExecuteScalar(); 
      } 
      finally 
      { 
       Database.Connection.Close(); 
       command.Parameters.Clear(); 
      } 
     } 
    } 
+2

私はそれがうまくいくと思いますが、実際にはEntity Frameworkを全く使用していません。 –

+0

良い点。いくつかの分析の後、EFは私たちの使用のために働かないでしょう。単一のテーブルからのクエリは問題ありませんが、他のテーブルへの参加を開始するとすぐに、EFは非常に複雑になります。 –

関連する問題