pit*_*dis 2 entity-framework-core asp.net-core asp.net-core-2.0
使用Entity Framework 6,我能够使用执行原始SQL查询并使用未在DBContext中定义的自定义模型来存储查询的输出.一个简单的例子如下:
List<MyModel> data = context.Database.SqlQuery<MyModel>("SELECT Orders.OrderID, Customers.CustomerName FROM Orders INNER JOIN Customers ON Orders.CustomerID=Customers.CustomerID;").ToList();
Run Code Online (Sandbox Code Playgroud)
我执行一个SQL命令,我期待一个自定义模型列表.
我尝试用Entity Framework Core做类似的事情,我发现的最接近的例子将迫使我从DBContext定义一个属性.这将不允许我使用自定义模型来填充SQL服务器将返回的数据.
var books = context.Books.FromSql("SELECT * FROM Books").ToList();
Run Code Online (Sandbox Code Playgroud)
此查询通知实体框架核心该查询将返回书籍列表.有没有办法在Entity Framework Core中实现这样的东西?
Mar*_*tín 10
从.NET Core 2.1开始:
添加modelBuilder.Query<YourModel>()到OnModelCreating(ModelBuilder modelBuilder)
使用context.Query<YourModel>().FromSql(rawSql)获得的数据
问题是关于 .NET Core 2。现在我有了一个解决方案,我将把它写在这里,以便其他人可以在需要时使用它。
首先我们在dbContext类中添加如下方法
public List<T> ExecSQL<T>(string query)
{
using (var command = Database.GetDbConnection().CreateCommand())
{
command.CommandText = query;
command.CommandType = CommandType.Text;
Database.OpenConnection();
List<T> list = new List<T>();
using (var result = command.ExecuteReader())
{
T obj = default(T);
while (result.Read())
{
obj = Activator.CreateInstance<T>();
foreach (PropertyInfo prop in obj.GetType().GetProperties())
{
if (!object.Equals(result[prop.Name], DBNull.Value))
{
prop.SetValue(obj, result[prop.Name], null);
}
}
list.Add(obj);
}
}
Database.CloseConnection();
return list;
}
}
Run Code Online (Sandbox Code Playgroud)
现在我们可以有以下代码。
List<Customer> Customers = _context.ExecSQL<Customer>("SELECT ......");
Run Code Online (Sandbox Code Playgroud)
这是我如何能够使其正常工作(为了完整性):
我的模型.cs:
public class MyModel
{
// The columns your SQL will return
public double? A { get; set; }
public double? B { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
添加仅从原始 EF 上下文类继承的类(我称之为 DbContextBase):
public class DbContext : DbContextBase
{
public virtual DbSet<MyModel> MyModels { get; set; }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
// Necessary, since our model isnt a EF model
modelBuilder.Entity<MyModel>(entity =>
{
entity.HasNoKey();
});
}
}
Run Code Online (Sandbox Code Playgroud)
使用该类(而不是您原来的 EF 上下文类):
// Use your new db subclass
using (var db = new DbContext())
{
var models = await db.MyModels.FromSqlRaw(...).ToListAsync(); // E.g.: "SELECT * FROM apple A JOIN banana B ON A.col = B.col"
}
Run Code Online (Sandbox Code Playgroud)
笔记:
FromSqlInterpolated代替
FromSqlRaw| 归档时间: |
|
| 查看次数: |
3130 次 |
| 最近记录: |