データベースのどこかに保存されるカスタムクエリを実行する必要があり、データテーブルまたはデータセットに戻って、列をtrueに自動生成するグリッドビューにバインドする必要があります。
私のすべてのデータアクセス層はエンティティフレームワークで完全に機能しますが、特定のシナリオではこれを行う必要があり、ado.netをエンティティフレームワークと組み合わせる必要があるのか、それともEFが何らかの方法でそれを行うことができるのか疑問に思います
データベースのどこかに保存されるカスタムクエリを実行する必要があり、データテーブルまたはデータセットに戻って、列をtrueに自動生成するグリッドビューにバインドする必要があります。
私のすべてのデータアクセス層はエンティティフレームワークで完全に機能しますが、特定のシナリオではこれを行う必要があり、ado.netをエンティティフレームワークと組み合わせる必要があるのか、それともEFが何らかの方法でそれを行うことができるのか疑問に思います
EntityFramework5の使用
context.Database.SqlQuery
また、Entity Framework 4の場合は、次のコードを使用します
context.ExecuteStoreQuery
public string BuyerSequenceNumberMax(int buyerId)
{
string sequenceMaxQuery = "SELECT TOP(1) btitosal.BuyerSequenceNumber FROM BuyerTakenItemToSale btitosal " +
"WHERE btitosal.BuyerID = " + buyerId +
"ORDER BY CONVERT(INT,SUBSTRING(btitosal.BuyerSequenceNumber,7, LEN(btitosal.BuyerSequenceNumber))) DESC";
var sequenceQueryResult = context.Database.SqlQuery<string>(sequenceMaxQuery).FirstOrDefault();
string buyerSequenceNumber = string.Empty;
if (sequenceQueryResult != null)
{
buyerSequenceNumber = sequenceQueryResult.ToString();
}
return buyerSequenceNumber;
}
リストを返すには、次のコードを使用します
public List<PanelSerialList> PanelSerialByLocationAndStock(string locationCode, byte storeLocation, string itemCategory, string itemCapacity, byte agreementType, string packageCode)
{
string panelSerialByLocationAndStockQuery = "SELECT isws.ItemSerialNo, im.ItemModel " +
"FROM Inv_ItemMaster im " +
"INNER JOIN " +
"Inv_ItemStockWithSerialNoByLocation isws " +
" ON im.ItemCode = isws.ItemCode " +
" WHERE isws.LocationCode = '" + locationCode + "' AND " +
" isws.StoreLocation = " + storeLocation + " AND " +
" isws.IsAvailableInStore = 1 AND " +
" im.ItemCapacity = '" + itemCapacity + "' AND " +
" isws.ItemSerialNo NOT IN ( " +
" Select sp.PanelSerialNo From Special_SpecialPackagePriceForResale sp " +
" Where sp.PackageCode = '" + packageCode + "' )";
context.Database.SqlQuery<PanelSerialList>(panelSerialByLocationAndStockQuery).ToList();
}
これが別の側面であり、より簡単なアプローチです。EntityFrameworkコンテキストを使用してSQL接続を取得します。
var connection = (System.Data.SqlClient.SqlConnection) _db.Database.Connection;
if (connection != null && connection.State == ConnectionState.Closed)
{
connection.Open();
}
var dt = new DataTable();
using (var com = new System.Data.SqlClient.SqlDataAdapter("Select * from Table", connection))
{
com.Fill(dt);
}
また、DataAdapter
またはその他の従来の方法を使用して、EF接続を使用してクエリを実行できます。
これは、動的に何かを行う場合や、エンティティにマップできない場合に非常に役立ちます。たとえば、DataTableで物事を取得できます。
上記の構文はEF5.0用です。
ADO.NET構造体(DataTableまたはDataSet)を返すことが目標の場合は、従来のADO.NETを使用してください。データをエンティティセットにバインドしてから、DataTableまたはDataSetに自分でデータを入力するよりも簡単です。
ただし、EntityFrameworkを介してカスタムクエリを実行することに本当に興味がある場合は、ExecuteQueryを確認してください。これにより、SQLクエリを実行し、結果をモデル内のエンティティにマップして戻すことができます。次に、IEnumerableの結果を取得し、それをDataTableまたはDataSetにマップするのはあなたの側の演習になります。したがって、「古き良きADO.NETメソッドを使用して実行する」という私の最初の答えです。
私はEF6を使用しており、ある日、動的SQL文字列を実行してDataTableを取得する方法が必要でした。最初に、私は単にキャストDbContext.Database.Connection
してSqlConnection
、すべての仕事をしました。DbConnection
テストでは機能しましたが、使用するGlimpseがタイプ付きの自己実装を注入するため、アプリケーションが壊れていましたGlimpse.Ado.AlternateType.GlimpseDbConnection
。DbConnectionとは独立して機能するアプローチが必要です。最後に、次のコードになります。
public class SqlDataProvider : ISqlDataProvider
{
private readonly DbContext _context;
public SqlDataProvider(DbContext context)
{
_context = context;
}
public DataTable GetDataTable(string sqlQuery)
{
try
{
DbProviderFactory factory = DbProviderFactories.GetFactory(_context.Database.Connection);
using (var cmd = factory.CreateCommand())
{
cmd.CommandText = sqlQuery;
cmd.CommandType = CommandType.Text;
cmd.Connection = _context.Database.Connection;
using (var adapter = factory.CreateDataAdapter())
{
adapter.SelectCommand = cmd;
var tb = new DataTable();
adapter.Fill(tb);
return tb;
}
}
}
catch (Exception ex)
{
throw new SqlExecutionException(string.Format("Error occurred during SQL query execution {0}", sqlQuery), ex);
}
}
そして、これはどのような場合でも機能しDbContext.Database.Connection
ますSqlConnection
。Glimpse.Ado.AlternateType.GlimpseDbConnection