使用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();
我执行一个SQL命令,我希望有一个自定义模型列表。
我尝试用Entity Framework Core做类似的事情,我发现的最接近的例子将迫使我从DBContext定义一个属性。这将不允许我使用自定义模型来填充SQL服务器将返回的数据。
var books = context.Books.FromSql("SELECT * FROM Books").ToList();
此查询通知Entity Framework Core查询将返回书籍列表。有没有办法在Entity Framework Core中实现这样的东西?
答案 0 :(得分:6)
从.NET Core 2.1:
将modelBuilder.Query<YourModel>()
添加到OnModelCreating(ModelBuilder modelBuilder)
使用context.Query<YourModel>().FromSql(rawSql)
获取数据
答案 1 :(得分:2)
这是我如何能够正常工作的原因:
MyModel.cs:
public class MyModel
{
// The columns your SQL will return
public double? A { get; set; }
public double? B { get; set; }
}
添加仅从您的原始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();
});
}
}
使用该类(而不是原始的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"
}
注意:
FromSqlInterpolated
而不是
FromSqlRaw
答案 2 :(得分:1)
请按照以下步骤操作:
如果您可以将其简化为尽可能通用的模型,可能会更好,但这不是必须的:
public class MyCustomModel
{
public string Text { get; set; }
public int Count { get; set; }
}
为您的自定义模型创建DbSet
public virtual DbSet<MyCustomModel> MyCustomModelName { get; set; }
请记住,指定您的自定义模型没有密钥
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
...
modelBuilder.Entity<MyCustomModel>().HasNoKey();
}
async public Task<List<MyCustomModel>> GetMyCustomData()
{
var rv = new List<MyCustomModel>();
using (var dataContext = new DbContext())
{
var sql = @"
select textField as 'Text', count(1) as 'Count'
from MyTable";
rv = await dataContext.Set<MyCustomModel>().FromSqlRaw(sql).ToListAsync();
}
return rv;
}
答案 3 :(得分:-1)
问题是关于.NET Core2。现在我有一个解决方案,我将在这里编写它,以便其他人可以在需要时使用它。
首先,我们在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;
}
}
现在我们可以有以下代码。
List<Customer> Customers = _context.ExecSQL<Customer>("SELECT ......");