Entity framework 使用实体框架核心生成和访问存储过程
我正在使用Visual Studio 2017实现Asp.Net核心Web API、实体框架核心、数据库优先方法。我已经成功地基于现有数据库生成了上下文和类文件。我需要使用我的上下文访问存储过程。在早期版本的entity framework中,在向导中选择存储过程对象并生成包含这些对象的edmx非常简单。然后,我可以通过实体框架公开的复杂类型对象访问存储过程。如何在实体框架核心中执行类似的操作。举个例子会有帮助吗?在EF Core和edmx文件中没有数据库优先的方法。相反,您必须使用Scaffold DbContext 安装Nuget软件包Microsoft.EntityFrameworkCore.Tools和Microsoft.EntityFrameworkCore.SqlServer.DesignEntity framework 使用实体框架核心生成和访问存储过程,entity-framework,asp.net-core,entity-framework-core,Entity Framework,Asp.net Core,Entity Framework Core,我正在使用Visual Studio 2017实现Asp.Net核心Web API、实体框架核心、数据库优先方法。我已经成功地基于现有数据库生成了上下文和类文件。我需要使用我的上下文访问存储过程。在早期版本的entity framework中,在向导中选择存储过程对象并生成包含这些对象的edmx非常简单。然后,我可以通过实体框架公开的复杂类型对象访问存储过程。如何在实体框架核心中执行类似的操作。举个例子会有帮助吗?在EF Core和edmx文件中没有数据库优先的方法。相反,您必须使用Scaffo
Scaffold-DbContext "Server=(localdb)\mssqllocaldb;Database=Blogging;Trusted_Connection=True;" Microsoft.EntityFrameworkCore.SqlServer -OutputDir Models
但是,这不会得到您的存储过程。它仍在工作中,跟踪问题
但是,要执行存储过程,请使用执行原始SQL查询的方法
e、 g
与参数一起使用
var productCategory= "Electronics";
var product = context.Products
.FromSql("EXECUTE dbo.GetProductByCategory {0}", productCategory)
.ToList();
或
执行原始SQL查询或存储过程有一定的限制。不能将其用于插入/更新/删除。如果要执行INSERT、UPDATE、DELETE查询,请使用EXECUTESQL命令
var categoryName = "Electronics";
dataContext.Database
.ExecuteSqlCommand("dbo.InsertCategory @p0", categoryName);
我们在EF Core中用于执行存储过程以获取数据的解决方法是使用FromSql方法,您可以通过以下方式执行存储过程:
List<Employee> employees = dbcontext.Employee
.FromSql("GetAllEmployees").ToList();
如果希望结果集与任何已定义的对象相同,则在执行存储过程时,上述示例可以正常工作。但是,如果您想要一个不受支持的结果集,该怎么办?据EF Core 2的开发人员称,这是一项即将推出的功能,但现在已经有了一个简单的解决方案 创建要用于输出的模型。此模型将表示输出,而不是数据库中的表
namespace Example.EF.Model
{
public class Sample
{
public int SampleID { get; set; }
public string SampleName { get; set; }
}
}
然后在您的上下文中添加一个新的DBSet和您的模型:
public virtual DbSet<Sample> Sample { get; set; }
我希望这对任何人都有帮助。罗伊特/哈罗德·贾维尔/萨米提供的解决方案很有效。我想补充一点,您可以创建一个单独的EF6项目来为ResultSet生成C#类,然后将这些文件复制到您的EFCore项目中。如果更改存储过程,可以使用此处讨论的方法更新结果文件: 如果需要相应的typescript接口,可以安装此VS2017扩展typescript定义生成器: 仍然有一些复制操作,但是它没有手动创建类那么繁琐 编辑:有一个用于生成dbconext的VS2017扩展。它不执行存储过程,但它从VS project提供了一个右键单击菜单项,而不是命令行Scaffold DbContext。My original post- 要调用存储过程并将结果放入EF Core中的模型列表中,我们必须遵循3个步骤 第1步。 您需要添加一个新类,就像您的实体类一样。其中应包含SP中所有列的属性。例如,如果SP返回两个名为
Id
和Name
的列,则新类应为
public class MySPModel
{
public int Id {get; set;}
public string Name {get; set;}
}
第2步。
然后,您必须将一个DbQuery
属性添加到SP的DBContext类中
public partial class Sonar_Health_AppointmentsContext : DbContext
{
public virtual DbSet<Booking> Booking { get; set; } // your existing DbSets
...
public virtual DbQuery<MySPModel> MySP { get; set; } // your new DbQuery
...
}
公共部分类声纳健康任命上下文:DbContext
{
公共虚拟数据库集预订{get;set;}//现有数据库集
...
公共虚拟数据库查询MySP{get;set;}//新数据库查询
...
}
第3步。
现在,您可以从DBContext调用SP并从中获取结果
var result = await _context.Query<MySPModel>().AsNoTracking().FromSql(string.Format("EXEC {0} {1}", functionName, parameter)).ToListAsync();
var result=await\u context.Query().AsNoTracking().FromSql(string.Format(“EXEC{0}{1}”,functionName,parameter)).toListSync();
我使用的是通用的UnitOfWork&Repository。因此,我执行SP的功能是
/// <summary>
/// Execute function. Be extra care when using this function as there is a risk for SQL injection
/// </summary>
public async Task<IEnumerable<T>> ExecuteFuntion<T>(string functionName, string parameter) where T : class
{
return await _context.Query<T>().AsNoTracking().FromSql(string.Format("EXEC {0} {1}", functionName, parameter)).ToListAsync();
}
//
///执行函数。使用此函数时要格外小心,因为存在SQL注入的风险
///
公共异步任务ExecuteFunction(字符串函数名,字符串参数),其中T:class
{
返回wait{u context.Query().AsNoTracking().FromSql(string.Format(“EXEC{0}{1}”,functionName,parameter)).toListSync();
}
希望这将有助于某人 您可以将ADO.NET用于DbContextAng示例可能与第227行重复这很有帮助?在运行Scaffold DbContext System.ArgumentNullException后,我发现以下错误:值不能为null。参数名称:ContentRootPath这样做,每当我们使用EF生成模型时,我们每次都需要手动添加dbset?您可以使用分部类将它们放在不同的文件中,以使其更简单。嘿@Sami,您能提供分部类示例吗?
EXEC ReturnAllSamples{id},{startdate},{enddate}
将生成不带参数的sql,并且可以接受sql注入。当您试图以这种方式执行过程时,NETCore会给出一条非常彻底的警告消息。最好使用被接受的答案是.FromSql(“EXECUTE dbo.GetProductByCategory{0}”,productCategory)
@SantiagoTrejo,我想他的意思是你可以创建你的DbContext的一部分(它们生成为partials)并在那里添加你的DbSet。这样,如果重新生成上下文,就不会丢失部分。如果SP使用join从多个表返回值,那么这将失败,那么我们应该使用什么方法呢。直到ef core拥有存储过程支持。
public class MySPModel
{
public int Id {get; set;}
public string Name {get; set;}
}
public partial class Sonar_Health_AppointmentsContext : DbContext
{
public virtual DbSet<Booking> Booking { get; set; } // your existing DbSets
...
public virtual DbQuery<MySPModel> MySP { get; set; } // your new DbQuery
...
}
var result = await _context.Query<MySPModel>().AsNoTracking().FromSql(string.Format("EXEC {0} {1}", functionName, parameter)).ToListAsync();
/// <summary>
/// Execute function. Be extra care when using this function as there is a risk for SQL injection
/// </summary>
public async Task<IEnumerable<T>> ExecuteFuntion<T>(string functionName, string parameter) where T : class
{
return await _context.Query<T>().AsNoTracking().FromSql(string.Format("EXEC {0} {1}", functionName, parameter)).ToListAsync();
}