是否有可能与entity framework运行本机SQL?
我试图search一个表中的XML字段,这是不支持与EF。
如果不使用纯Ado.net,可以使用EF进行本地SQL支持?
对于.NET Framework版本4及更高版本:如果查询不返回任何结果,则使用ObjectContext.ExecuteStoreCommand()
如果查询返回结果,则使用ObjectContext.ExecuteStoreQuery
。
对于以前的.NET Framework版本,以下是一个示例说明如何操作。 如果查询返回结果,则根据需要replaceExecuteNonQuery()。
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 } }
使用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代码优先:在数据库创build时执行SQL文件
对于entity framework5使用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<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(); }
从.NET 4开始,你可以使用ExecuteStoreQuery
方法:
var list = myDBEntities.ExecuteStoreQuery<MyClass>(MyClass.sql);
myDBEntities从ObjectContextinheritance而来。
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; } }
注意,MyTable是真实的表名,而不是EF类。
把事情简单化
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()); }
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); } }
那么2017年我们对这一切有何评论? 80k的咨询意味着在EF中运行SQL请求是很多人想要做的。 但为什么? 为了什么好处?
贾斯汀,一个20倍于我的名声的大师,在接受的答案中给了我们一个静态的方法,看起来就像是等价的ADO代码。 一定要复制它,因为有一些微妙之处,不要错。 而且由于没有规定适当的参数,因此您必须将查询与运行时参数连接起来。 所以这个方法的所有用户都会使用string方法(脆弱的,不可testing的,SQL注入)构build他们的SQL,而且他们都不会是unit testing。
其他答案也有同样的错误,只有更多。 用双引号括起来的SQL。 SQL注入机会散布在四周。 尊敬的同龄人,这绝对是野蛮的行为。 如果这是C#正在生成,将会有一场火焰战争。 我们甚至不接受以这种方式生成HTML,但以某种方式确定SQL。 我知道查询参数不是问题的主题,但我们复制并重用了我们所看到的内容,这里的答案既是模型又是人们正在做什么的遗憾。
EF是否融化了我们的大脑? EF不希望你使用SQL,所以为什么要用EF来做SQL。
想要使用SQL与关系数据库进行交谈对于成年人来说是一种健康,正常的冲动。 QueryFirst显示了如何智能地完成这项工作,sql中的.sql文件,在您input时进行validation,以及表和列的智能感知。 C#包装器是由该工具生成的,因此您的查询可以在代码中被发现,智能感知您的input和结果。 端到端强大的打字,而不必担心types。 不需要记住列名或索引。 还有很多其他的好处…连接的诱惑被删除 。 error handling您的连接的可能性也。 您的所有查询和访问它们的代码都将不断与您的开发数据库进行集成testing。 您的数据库中的架构更改将popup为应用程序中的编译错误。 我们甚至在包装器中生成一个自测方法,所以你可以在现有的生产数据库上testing你的应用程序的新版本,而不是等待电话响铃。 任何人仍然需要说服力?
免责声明:我写了QueryFirst 🙂