表示する必要のある多くのストアード・プロシージャーがあるシステムを使用しています。オブジェクトごとにエンティティを作成することは現実的ではありません。
DataTable
を使用してExecuteStoreQuery
を返すことは可能ですか?
public ObjectResult<DataTable> MethodName(string fileSetName) {
using (var dataContext = new DataContext(_connectionString))
{
var returnDataTable = ((IObjectContextAdapter)dataContext).ObjectContext.ExecuteStoreQuery<DataTable>("SP_NAME","SP_PARAM");
return returnDataTable;
}
いいえ、うまくいくとは思いません-Entity Frameworkはentitiesを返すように設計されており、DataTable
オブジェクトを返すことを意図していません。
DataTable
オブジェクトが必要な場合は、代わりにストレートADO.NETを使用してください。
はい、可能ですが、動的な結果セットまたは生のSQLにのみ使用する必要があります。
_public DataTable ExecuteStoreQuery(string commandText, params Object[] parameters)
{
DataTable retVal = new DataTable();
retVal = context.ExecuteStoreQuery<DataTable>(commandText, parameters).FirstOrDefault();
return retVal;
}
_
編集:おそらくメソッドを実行できてもDataTable
を使用できないため、Entity Frameworkを使用するよりも古典的なADO.NETを使用してデータモデルを取得することをお勧めします。context.ExecuteStoreQuery<DataTable>(commandText, parameters).FirstOrDefault();
ADO.NETの例:
_public DataSet GetResultReport(int questionId)
{
DataSet retVal = new DataSet();
EntityConnection entityConn = (EntityConnection)context.Connection;
SqlConnection sqlConn = (SqlConnection)entityConn.StoreConnection;
SqlCommand cmdReport = new SqlCommand([YourSpName], sqlConn);
SqlDataAdapter daReport = new SqlDataAdapter(cmdReport);
using (cmdReport)
{
SqlParameter questionIdPrm = new SqlParameter("QuestionId", questionId);
cmdReport.CommandType = CommandType.StoredProcedure;
cmdReport.Parameters.Add(questionIdPrm);
daReport.Fill(retVal);
}
return retVal;
}
_
このメソッドは、エンティティフレームワークからの接続文字列を使用して、この例ではMySQLデータベースへのADO.NET接続を確立します。
using MySql.Data.MySqlClient;
public DataSet GetReportSummary( int RecordID )
{
var context = new catalogEntities();
DataSet ds = new DataSet();
using ( MySqlConnection connection = new MySqlConnection( context.Database.Connection.ConnectionString ) )
{
using ( MySqlCommand cmd = new MySqlCommand( "ReportSummary", connection ) )
{
MySqlDataAdapter adapter = new MySqlDataAdapter( cmd );
adapter.SelectCommand.CommandType = CommandType.StoredProcedure;
adapter.SelectCommand.Parameters.Add( new MySqlParameter( "@ID", RecordID ) );
adapter.Fill( ds );
}
}
return ds;
}
はい、それはこのように簡単に行うことができます:
var table = new DataTable();
using (var ctx = new SomeContext())
{
var cmd = ctx.Database.Connection.CreateCommand();
cmd.CommandText = "Select Col1, Col2 from SomeTable";
cmd.Connection.Open();
table.Load(cmd.ExecuteReader());
}
原則として、EFアプリケーション内ではDataSetを使用しないでください。しかし、本当に必要な場合(たとえば、レポートをフィードする場合)は、そのソリューションが機能するはずです(EF 6コードです)。
DataSet GetDataSet(string sql, CommandType commandType, Dictionary<string, Object> parameters)
{
// creates resulting dataset
var result = new DataSet();
// creates a data access context (DbContext descendant)
using (var context = new MyDbContext())
{
// creates a Command
var cmd = context.Database.Connection.CreateCommand();
cmd.CommandType = commandType;
cmd.CommandText = sql;
// adds all parameters
foreach (var pr in parameters)
{
var p = cmd.CreateParameter();
p.ParameterName = pr.Key;
p.Value = pr.Value;
cmd.Parameters.Add(p);
}
try
{
// executes
context.Database.Connection.Open();
var reader = cmd.ExecuteReader();
// loop through all resultsets (considering that it's possible to have more than one)
do
{
// loads the DataTable (schema will be fetch automatically)
var tb = new DataTable();
tb.Load(reader);
result.Tables.Add(tb);
} while (!reader.IsClosed);
}
finally
{
// closes the connection
context.Database.Connection.Close();
}
}
// returns the DataSet
return result;
}
EntityFrameworkを使用してDataTableを返す最も簡単な方法は、次のことです。
MetaTable metaTable = Global.DefaultModel.GetTable("Your EntitySetName");
例えば:
MetaTable metaTable = Global.DefaultModel.GetTable("Employees");
Entity Frameworkベースのソリューションでは、効率上の理由から、Linqクエリの1つをSQLに置き換える必要があります。また、2つのストアドプロシージャに渡すテーブル値パラメーターを作成できるように、1つのストアドプロシージャからのDataTable
で結果を取得したいと考えています。そう:
私はSQLを使用しています
DataSet
欲しくない
IEnumerable
の反復はおそらくそれを削減するつもりはありません-効率上の理由から
また、私はEF6を使用しているので、要求された元のポスターとして_DbContext.SqlQuery
_よりも_ObjectContext.ExecuteStoreQuery
_を優先します。
しかし、これはうまくいかないことがわかりました:
_Context.Database.SqlQuery<DataTable>(sql, parameters).FirstOrDefault();
これが私の解決策です。 ADO.NETを使用してフェッチされたDataTable
を返しますSqlDataReader
-読み取り専用データのSqlDataAdapter
よりも高速だと思います。 ADO.Netを使用しているため、質問には厳密には回答しませんが、DbContext
から接続を取得した後の方法を示しています
_ protected DataTable GetDataTable(string sql, params object[] parameters)
{
//didn't work - table had no columns or rows
//return Context.Database.SqlQuery<DataTable>(sql, parameters).FirstOrDefault();
DataTable result = new DataTable();
SqlConnection conn = Context.Database.Connection as SqlConnection;
if(conn == null)
{
throw new InvalidCastException("SqlConnection is invalid for this database");
}
using (SqlCommand cmd = new SqlCommand(sql, conn))
{
cmd.Parameters.AddRange(parameters);
conn.Open();
using (SqlDataReader reader = cmd.ExecuteReader())
{
result.Load(reader);
}
return result;
}
}
_
多分あなたのストアドプロシージャは複合型を返す可能性がありますか? http://blogs.msdn.com/b/somasegar/archive/2010/01/11/entity-framework-in-net-4.aspx