Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/266.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 是否使用实体框架执行自定义sql?_C#_Entity Framework_Entity Framework 4_Ado.net - Fatal编程技术网

C# 是否使用实体框架执行自定义sql?

C# 是否使用实体框架执行自定义sql?,c#,entity-framework,entity-framework-4,ado.net,C#,Entity Framework,Entity Framework 4,Ado.net,我需要执行一个customquery,它将保存在数据库的某个地方,我需要它返回到datatable或dataset中,并将其绑定到一个gridview,该gridview将自动生成列为true 我所有的数据访问层都可以完美地使用entity framework,但对于某些特定场景,我需要这样做,我想知道是否应该将ado.net与entity framework结合起来,或者EF是否可以以某种方式实现这一点,如果您的目标是返回ado.net结构(DataTable或DataSet),那么只需使用经

我需要执行一个customquery,它将保存在数据库的某个地方,我需要它返回到datatable或dataset中,并将其绑定到一个gridview,该gridview将自动生成列为true


我所有的数据访问层都可以完美地使用entity framework,但对于某些特定场景,我需要这样做,我想知道是否应该将ado.net与entity framework结合起来,或者EF是否可以以某种方式实现这一点,如果您的目标是返回ado.net结构(DataTable或DataSet),那么只需使用经典的ado.net即可。您会发现,这比尝试将数据绑定到实体集,然后自己填充数据表或数据集更容易

但是,如果您确实对通过EntityFramework运行自定义查询感兴趣,请看一看。它允许您执行SQL查询并将结果映射回模型中的实体。然后,获取IEnumerable结果并将其映射到DataTable或DataSet将是您的一项练习。因此,我最初的回答是“只需使用好的ol’风格的ADO.NET方法即可。”

对于实体框架5使用

context.Database.SqlQuery


对于实体框架4,请使用以下代码

context.ExecuteStoreQuery


公共字符串BuyerSequenceNumberMax(int-buyerId)
{
string sequenceMaxQuery=“从BuyerTakenItemToSale btitosal中选择TOP(1)btitosal.BuyerSequenceNumber”+
“其中btitosal.BuyerID=“+BuyerID+
“按转换顺序(INT,子字符串(btitosal.BuyerSequenceNumber,7,LEN(btitosal.BuyerSequenceNumber)))描述”;
var sequenceQueryResult=context.Database.SqlQuery(sequenceMaxQuery).FirstOrDefault();
string buyerSequenceNumber=string.Empty;
if(sequenceQueryResult!=null)
{
buyerSequenceNumber=sequenceQueryResult.ToString();
}
返回买方序列号;
}
要返回列表,请使用以下代码

 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();


}
公共列表面板SerialByLocation和Stock(字符串位置代码、字节存储位置、字符串项目类别、字符串项目容量、字节协议类型、字符串包代码)
{
string panelSerialByLocationAndStockQuery=“选择isws.ItemSerialNo,im.ItemModel”+
“来自Inv_ItemMaster im”+
“内部联接”+
“Inv_ItemStockwith SerialNobyLocation isws”+
“在im.ItemCode=isws.ItemCode上”+
“其中isws.LocationCode='”+LocationCode+“'和”+
“isws.StoreLocation=“+StoreLocation+”和”+
“isws.IsAvailableInStore=1和”+
“im.ItemCapacity='”+ItemCapacity+“'和”+
“isws.ItemSerialNo不在(”+
“从特殊包装价格中选择sp.PanelSerialNo用于转售sp”+
“其中sp.PackageCode=”“+PackageCode+”)”;
context.Database.SqlQuery(panelSerialByLocationAndStockQuery).ToList();
}

这是另一个维度和更简单的方法。使用实体框架上下文获取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连接执行查询

当我们动态地做一些事情或者当我们不能映射到一个实体时,这将非常有用。例如,我们可以在数据表中获取内容


上面的语法是针对EF5.0的。

我使用EF6,有一天我需要一种方法来执行动态SQL字符串并获取数据表。首先,我只是将
DbContext.Database.Connection
转换为
SqlConnection
,并完成了整个工作。它在测试中起作用,但应用程序被破坏了,因为我们使用的scape将
DbConnection
的自我实现注入了类型
scape.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
的测试,以及
scape.Ado.AlternateType.GlimpseDbConnection

如果您不确定是否已清除所有输入,使用SQL参数防止SQL注入攻击。如果调用返回多个结果集的存储过程,则不支持MARS?SqlQuery意味着每次调用只能处理一种类型的结果集。
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);
        }
    }