用entity framework执行自定义sql?

我需要执行一个自定义查询,它将被保存在数据库中的某个地方,我需要它返回数据表或数据集并将其绑定到gridview,它将自动生成列为true。

我的所有数据访问层都与entity framework完美配合,但对于某些特定场景,我需要这样做,我想知道我是否应该将ado.net与entity framework结合起来,或者如果EF能够以某种方式实现它

如果您的目标是返回ADO.NET结构(DataTable或DataSet),那么只需使用经典的ADO.NET即可。 您会发现它比尝试将数据绑定到实体集然后自己填充DataTable或DataSet更容易。

但是,如果您真的真的有兴趣通过EntityFramework运行自定义查询,请查看ExecuteQuery 。 它允许您执行SQL查询并将结果映射回模型中的实体。 然后,您将获取IEnumerable结果并将其映射到DataTable或DataSet。 因此,我原来的答案是“用好的OL’方式做ADO.NET方法。”

对于Entity Framework 5使用

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(sequenceMaxQuery).FirstOrDefault(); string buyerSequenceNumber = string.Empty; if (sequenceQueryResult != null) { buyerSequenceNumber = sequenceQueryResult.ToString(); } return buyerSequenceNumber; } 

对于Return a List,请使用以下代码

  public List 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(panelSerialByLocationAndStockQuery).ToList(); } 

这是另一个维度和更简单的方法。 使用您的entity framework获取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中获取内容。

上面的语法适用于EF 5.0

我使用EF6,有一天我需要执行动态SQL字符串并获取DataTable。 首先,我只是将DbContext.Database.ConnectionSqlConnection并完成整个工作。 它适用于测试,但是应用程序被破坏了,因为我们使用的Glimpse使用类型Glimpse.Ado.AlternateType.GlimpseDbConnection注入DbConnection自我实现。 我需要独立于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.ConnectionSqlConnectionGlimpse.Ado.AlternateType.GlimpseDbConnection