是否可以使用实体框架运行本机sql?

时间:2009-05-27 12:04:26

标签: sql entity-framework ado.net

我正在尝试搜索表格中的XML字段,EF不支持。

如果不使用纯Ado.net,可以在EF中使用本机SQL支持吗?

7 个答案:

答案 0 :(得分:72)

对于.NET Framework版本4及更高版本:如果查询未返回任何结果,请使用ObjectContext.ExecuteStoreCommand(),如果查询返回结果,请使用ObjectContext.ExecuteStoreQuery

对于以前的.NET Framework版本,这里有一个示例说明了要做什么。如果查询返回结果,请根据需要替换ExecuteNonQuery()。

static void ExecuteSql(ObjectContext c, string sql)
{
    var entityConnection = (System.Data.EntityClient.EntityConnection)c.Connection;
    DbConnection conn = entityConnection.StoreConnection;
    ConnectionState initialState = conn.State;
    try
    {
        if (initialState != ConnectionState.Open)
            conn.Open();  // open connection if not already open
        using (DbCommand cmd = conn.CreateCommand())
        {
            cmd.CommandText = sql;
            cmd.ExecuteNonQuery();
        }
    }
    finally
    {
        if (initialState != ConnectionState.Open)
            conn.Close(); // only close connection if not initially open
    }
}

答案 1 :(得分:24)

使用Entity Framework 5.0,您可以使用ExecuteSqlCommand执行多行/多命令纯SQL语句。这样您就不需要提供任何后备对象来存储返回的值,因为该方法返回一个int(执行命令后数据库返回的结果)。

样品:

context.Database.ExecuteSqlCommand(@
"-- Script Date: 10/1/2012 3:34 PM  - Generated by ExportSqlCe version 3.5.2.18
SET IDENTITY_INSERT [Students] ON;

INSERT INTO [Students] ([StudentId],[FirstName],[LastName],[BirthDate],[Address],[Neighborhood],[City],[State],[Phone],[MobilePhone],[Email],[Enrollment],[Gender],[Status]) VALUES (12,N'First Name',N'SecondName',{ts '1988-03-02 00:00:00.000'},N'RUA 19 A, 60',N'MORADA DO VALE',N'BARRA DO PIRAÍ',N'Rio de Janeiro',N'3346-7125',NULL,NULL,{ts '2011-06-04 21:25:26.000'},2,1);

INSERT INTO [Students] ([StudentId],[FirstName],[LastName],[BirthDate],[Address],[Neighborhood],[City],[State],[Phone],[MobilePhone],[Email],[Enrollment],[Gender],[Status]) VALUES (13,N'FirstName',N'LastName',{ts '1976-04-12 00:00:00.000'},N'RUA 201, 2231',N'RECANTO FELIZ',N'BARRA DO PIRAÍ',N'Rio de Janeiro',N'3341-6892',NULL,NULL,{ts '2011-06-04 21:38:38.000'},2,1);
");

有关详情,请点击此处:Entity Framework Code First: Executing SQL files on database creation

答案 2 :(得分:17)

对于 实体框架5 ,请使用 context.Database.SqlQuery

对于 实体框架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;
    }

要返回List,请使用以下代码:

 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 + "' )";


    return context.Database.SqlQuery<PanelSerialList>(panelSerialByLocationAndStockQuery).ToList();


}

答案 3 :(得分:16)

从.NET 4开始,您可以使用ExecuteStoreQuery方法:

var list = myDBEntities.ExecuteStoreQuery<MyClass>(MyClass.sql);

其中myDBEntities继承自ObjectContext。

class MyClass
{
    /* You can change query to more complicated, e.g. with joins */
    public const string sql = @"select [MyTable].[MyField] from [MyTable]";
    public string MyField { get; set; }
}

请注意,MyTable是真正的表名,而不是EF类。

答案 4 :(得分:3)

保持简单

using (var context = new MyDBEntities())
{
    var m = context.ExecuteStoreQuery<MyDataObject>("Select * from Person", string.Empty);
    //Do anything you wonna do with 
    MessageBox.Show(m.Count().ToString());
}

答案 5 :(得分:2)

public class RaptorRepository<T>
    where T : class
{
    public RaptorRepository()
        : this(new RaptorCoreEntities())
    {
    }

    public RaptorRepository(ObjectContext repositoryContext)
    {
        _repositoryContext = repositoryContext ?? new RaptorCoreEntities();
        _objectSet = repositoryContext.CreateObjectSet<T>();
    }

    private ObjectContext _repositoryContext;
    private ObjectSet<T> _objectSet;
    public ObjectSet<T> ObjectSet
    {
        get
        {
            return _objectSet;
        }
    }


    public void DeleteAll()
    {
        _repositoryContext
            .ExecuteStoreCommand("DELETE " + _objectSet.EntitySet.ElementType.Name);
    }
}

答案 6 :(得分:0)

那么2017年我们怎么说呢? 80k的咨询表明,在EF中运行SQL请求是很多人想要做的事情。但为什么?为了什么好处?

Justin,一位拥有20倍声望的大师,在接受的答案中给了我们一个静态的方法,看起来像等效的ADO代码一样。一定要好好复制,因为有一些细微之处,不会出错。而且您不得不将查询与运行时参数连接起来,因为没有提供适当的参数。因此,此方法的所有用户都将使用字符串方法(脆弱,不可测试,sql注入)构建SQL,并且它们都不会进行单元测试。

其他答案有相同的错误,只有更多。 SQL埋在双引号中。 SQL注入机会自由散乱。尊敬的同行,这绝对是野蛮的行为。如果这是生成C#,就会发生火焰战。我们甚至不接受以这种方式生成HTML,但不知何故它可以用于SQL。我知道查询参数不是问题的主题,但我们复制并重用我们看到的内容,这里的答案都是人们正在做的模型和测试。

EF是否融化了我们的大脑? EF不希望您使用SQL,因此为什么要使用EF来执行SQL。

想要使用SQL与关系数据库交谈是成年人健康,正常的冲动。 QueryFirst 显示了如何智能地完成此操作,您的sql in .sql文件,在您键入时验证,并使用表和列的intellisense。 C#包装器由该工具生成,因此您的查询在代码中可被发现,并具有用于输入和结果的智能感知。端到端的强力打字,无需担心类型。无需记住列名或其索引。还有许多其他好处......连接的诱惑是删除。也错误处理你的连接的可能性。您的所有查询和访问它们的代码都会针对您的dev DB进行持续集成测试。数据库中的架构更改会在应用程序中弹出为编译错误。我们甚至在包装器中生成自测试方法,因此您可以针对现有的生产数据库测试您的应用程序的新版本,而不是等待手机响铃。还有人需要说服吗?

免责声明:我写过QueryFirst: - )