È ansible eseguire SQL nativo con il framework di quadro?

Sto cercando di cercare un campo XML all’interno di una tabella, Questo non è supportato con EF.

Senza usare puro Ado.net è ansible avere un supporto SQL nativo con EF?

Per .NET Framework versione 4 e successive: utilizzare ObjectContext.ExecuteStoreCommand() se la query non restituisce risultati e utilizzare ObjectContext.ExecuteStoreQuery se la query restituisce risultati.

Per le precedenti versioni di .NET Framework, ecco un esempio che illustra cosa fare. Sostituire ExecuteNonQuery () secondo necessità se la query restituisce risultati.

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

Utilizzando Entity Framework 5.0 è ansible utilizzare ExecuteSqlCommand per eseguire istruzioni SQL puramente multilinea / multi-comando. In questo modo non sarà necessario fornire alcun object di supporto per memorizzare il valore restituito poiché il metodo restituisce un int (il risultato restituito dal database dopo l’esecuzione del comando).

Campione:

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

Per ulteriori informazioni, consultare qui: Codice del framework Entity First: Esecuzione di file SQL sulla creazione del database

Per Entity Framework 5 utilizzare context.Database.SqlQuery .

E per Entity Framework 4 usa context.ExecuteStoreQuery il seguente codice:

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

Per restituire un elenco utilizzare il seguente codice:

  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 + "' )"; return context.Database.SqlQuery(panelSerialByLocationAndStockQuery).ToList(); } 

Dal momento che .NET 4 è ansible utilizzare il metodo ExecuteStoreQuery :

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

dove myDBEntities è ereditato da ObjectContext.

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

Notare che MyTable è il nome reale della tabella, non la class EF.

Mantienilo semplice

 using (var context = new MyDBEntities()) { var m = context.ExecuteStoreQuery("Select * from Person", string.Empty); //Do anything you wonna do with MessageBox.Show(m.Count().ToString()); } 
 public class RaptorRepository where T : class { public RaptorRepository() : this(new RaptorCoreEntities()) { } public RaptorRepository(ObjectContext repositoryContext) { _repositoryContext = repositoryContext ?? new RaptorCoreEntities(); _objectSet = repositoryContext.CreateObjectSet(); } private ObjectContext _repositoryContext; private ObjectSet _objectSet; public ObjectSet ObjectSet { get { return _objectSet; } } public void DeleteAll() { _repositoryContext .ExecuteStoreCommand("DELETE " + _objectSet.EntitySet.ElementType.Name); } } 

Quindi cosa diciamo di tutto questo nel 2017? Le consultazioni 80k suggeriscono che l’esecuzione di una richiesta SQL in EF è qualcosa che un sacco di gente vuole fare. Ma perché? Per quale beneficio?

Justin, un guru con 20 volte la mia reputazione, nella risposta accettata ci dà un metodo statico che sembra linea per linea come l’equivalente codice ADO. Assicurati di copiarlo bene perché ci sono alcune sottigliezze per non sbagliare. E tu sei obbligato a concatenare la tua query con i tuoi parametri di runtime dato che non c’è alcuna disposizione per i parametri corretti. Quindi tutti gli utenti di questo metodo costruiranno il loro SQL con metodi stringa (fragile, non testabile, iniezione sql), e nessuno di questi sarà un test unitario.

Le altre risposte hanno gli stessi difetti, solo più mali. SQL sepolto tra virgolette. Opportunità di iniezione SQL liberamente disperse. Coetanei stimati, questo è un comportamento assolutamente selvaggio. Se fosse generato C #, ci sarebbe stata una guerra di fuoco. Non accettiamo nemmeno la generazione di HTML in questo modo, ma in qualche modo è OK per SQL. So che i parametri della query non erano l’argomento della domanda, ma noi copiamo e riutilizziamo ciò che vediamo, e le risposte qui sono entrambi modelli e testamenti di ciò che la gente sta facendo.

EF ha sciolto il nostro cervello? EF non vuole che tu usi SQL, quindi perché usare EF per fare SQL.

Volere usare SQL per parlare con un DB relazionale è un impulso sano e normale negli adulti. QueryFirst mostra come ciò potrebbe essere fatto in modo intelligente, il file sql in .sql, convalidato durante la digitazione, con intellisense per tabelle e colonne. Il wrapper C # è generato dallo strumento, quindi le tue query diventano rilevabili nel codice, con intellisense per i tuoi input e risultati. Fine alla fine digitazione forte, senza mai doversi preoccupare di un tipo. Non è necessario ricordare mai un nome di colonna o il suo indice. E ci sono molti altri benefici … La tentazione di concatenare viene rimossa . La possibilità di maltrattare le connessioni anche. Tutte le tue domande e il codice che le accede sono continuamente testati per l’integrazione con il tuo DB di sviluppo. Le modifiche allo schema nel tuo DB appaiono come errori di compilazione nella tua app. Abbiamo perfino generato un metodo di auto test nel wrapper, così puoi testare nuove versioni della tua app contro i database di produzione esistenti, piuttosto che aspettare che squilli il telefono. Qualcuno ha ancora bisogno di essere convincente?

Disclaimer: Ho scritto QueryFirst 🙂