2009-05-27 113 views
64

我正在嘗試搜索表格中的XML字段,這與EF不兼容。是否可以使用實體框架運行本機sql?

如果不使用純Ado.net,可以使用EF進行本地SQL支持?

+0

請澄清一下你的問題。當你問到「原生SQL支持」時,你的意思不僅僅是「支持XML列」嗎?你還指什麼?另外,您對XML列有什麼問題?它沒有進入實體,或者當你嘗試使用它時是否存在問題?另外,請說出你使用的是什麼版本? 2008年,2008年SP1,2010年CTP或Beta 1? – 2009-05-27 12:17:02

回答

71

對於.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 
    } 
} 
+38

這個答案已過時。看到這篇文章http://geekswithblogs.net/rgupta/archive/2010/06/23/entity-framework-v4-ndash-tips-and-tricks.aspx。您可以直接從實體框架執行Sql,而不需要使用** ExecuteStoreCommand **或** ExecuteStoreQuery **直接執行實體實例。 – 2011-07-29 03:11:28

+9

請記住,這些方法不受DbContext支持,但存在Database.ExecuteSqlCommand()或Database.SqlQuery 。 – nicodemus13 2011-12-01 14:46:45

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); 
    } 
} 
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類。

23

使用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

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; 
    } 

要返回一個列表使用下面的代碼:

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

保持簡單

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

那麼我們在2017年對所有這些問題有何評論? 80k的諮詢意味着在EF中運行SQL請求是很多人想要做的。但爲什麼?爲了什麼好處?

賈斯汀是一位有20倍我聲望的古茹,在接受的答案中給了我們一種靜態方法,它看起來就像是等效的ADO代碼。一定要複製它,因爲有一些微妙的東西不會錯。由於沒有提供適當的參數,因此您必須將查詢與運行時參數連接起來。所以這個方法的所有用戶都會用字符串方法(脆弱的,不可測試的,SQL注入)構造他們的SQL,並且他們都不會進行單元測試。

其他答案有同樣的錯誤,只有更多。嵌入在雙引號中的SQL。 SQL注入機會散佈在周圍。尊敬的同齡人,這絕對是野蠻的行爲。如果這是C#正在生成,那麼會出現一場火焰戰。我們甚至不接受通過這種方式生成HTML,但以某種方式確定SQL。我知道查詢參數不是問題的主題,但我們複製並重用了我們所看到的內容,這裏的答案既是模型又是人們正在做什麼的遺憾。

EF是否融化了我們的大腦? EF不希望您使用SQL,那麼爲什麼要使用EF來執行SQL。

想要使用SQL與關係數據庫進行交談對於成年人來說是一種健康正常的衝動。 QueryFirst顯示瞭如何智能地完成此操作,sql中的.sql文件,在鍵入時進行驗證,以及表和列的智能感知。 C#包裝器是由該工具生成的,因此您的查詢在代碼中可以被發現,智能感知您的輸入和結果。端到端的強大打字,無需擔心類型。不需要記住列名或其索引。還有很多其他的好處......連接的誘惑是刪除。錯誤處理連接的可能性也是。您的所有查詢和訪問它們的代碼都會持續與您的開發數據庫進行集成測試。您的數據庫中的架構更改將彈出,因爲您的應用中存在編譯錯誤。我們甚至在封裝器中生成自測方法,因此您可以在現有生產數據庫上測試新版本的應用程序,而不是等待電話響鈴。任何人仍然需要說服力?我寫了QueryFirst :-)

相關問題