Sub*_*kar 5 c# sql-server ef-database-first entity-framework-core asp.net-core-mvc
在过去的几天里,我正在寻找一些关于如何使用控制器方法调用Stored Procedure内部的教程.Web APIEntityFramework 7
我通过的所有教程都反过来展示它,即Code First接近.但我已经有了一个数据库,我需要用它来构建一个Web API.各种业务逻辑已经编写为存储过程和视图,我必须使用来自Web API的那些逻辑.
问题1:这是否可以继续使用上述Database First方法EF7并使用数据库对象?
我EntityFramework 6.1.3通过以下NuGet命令安装到我的包中:
install-package EntityFramework
它将6.1.3版本添加到我的项目中,但立即开始向我显示错误消息(请参阅下面的屏幕截图).我不清楚如何解决这个问题.
我有另一个测试项目,在其中project.json我可以看到两个条目如下:
"EntityFramework.MicrosoftSqlServer": "7.0.0-rc1-final",
"EntityFramework.MicrosoftSqlServer.Design": "7.0.0-rc1-final",
但是,当我在Nu-Get包管理器中搜索时,我不会看到这个版本!只有6.1.3即将到来.
我的主要目标是从现有数据库中使用已编写的存储过程和视图.
1)我不想使用ADO.Net,而是我想ORM使用EntityFramework
2)如果EntityFramework 6.1.3有来电的能力Stored Procs,并Views从已经存在的数据库,我怎么能解决错误(截图)?
实现这一目标的最佳做法是什么?
Ole*_*leg 11
我希望我正确理解你的问题.例如dbo.spGetSomeData,您在数据库中存在STORED PROCEDURE,它返回包含某些字段的某些项的列表,您需要从Web API方法提供数据.
实施可以是以下几点.您可以定义一个空的 DbContext:
public class MyDbContext : DbContext
{
}
Run Code Online (Sandbox Code Playgroud)
并appsettings.json使用连接字符串定义数据库
{
"Data": {
"DefaultConnection": {
"ConnectionString": "Server=(localdb)\\mssqllocaldb;Database=MyDb;Trusted_Connection=True;MultipleActiveResultSets=true"
}
}
}
Run Code Online (Sandbox Code Playgroud)
您应该使用Microsoft.Extensions.DependencyInjection添加MyDbContext到
public class Startup
{
// property for holding configuration
public IConfigurationRoot Configuration { get; set; }
public Startup(IHostingEnvironment env)
{
// Set up configuration sources.
var builder = new ConfigurationBuilder()
.AddJsonFile("appsettings.json")
.AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true);
.AddEnvironmentVariables();
// save the configuration in Configuration property
Configuration = builder.Build();
}
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
// Add framework services.
services.AddMvc()
.AddJsonOptions(options => {
options.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver();
});
services.AddEntityFramework()
.AddSqlServer()
.AddDbContext<MyDbContext>(options => {
options.UseSqlServer(Configuration["ConnectionString"]);
});
}
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
...
}
}
Run Code Online (Sandbox Code Playgroud)
现在,您可以按以下方式实施WebApi操作:
[Route("api/[controller]")]
public class MyController : Controller
{
public MyDbContext _context { get; set; }
public MyController([FromServices] MyDbContext context)
{
_context = context;
}
[HttpGet]
public async IEnumerable<object> Get()
{
var returnObject = new List<dynamic>();
using (var cmd = _context.Database.GetDbConnection().CreateCommand()) {
cmd.CommandText = "exec dbo.spGetSomeData";
cmd.CommandType = CommandType.StoredProcedure;
// set some parameters of the stored procedure
cmd.Parameters.Add(new SqlParameter("@someParam",
SqlDbType.TinyInt) { Value = 1 });
if (cmd.Connection.State != ConnectionState.Open)
cmd.Connection.Open();
var retObject = new List<dynamic>();
using (var dataReader = await cmd.ExecuteReaderAsync())
{
while (await dataReader.ReadAsync())
{
var dataRow = new ExpandoObject() as IDictionary<string, object>;
for (var iFiled = 0; iFiled < dataReader.FieldCount; iFiled++) {
// one can modify the next line to
// if (dataReader.IsDBNull(iFiled))
// dataRow.Add(dataReader.GetName(iFiled), dataReader[iFiled]);
// if one want don't fill the property for NULL
// returned from the database
dataRow.Add(
dataReader.GetName(iFiled),
dataReader.IsDBNull(iFiled) ? null : dataReader[iFiled] // use null instead of {}
);
}
retObject.Add((ExpandoObject)dataRow);
}
}
return retObject;
}
}
}
Run Code Online (Sandbox Code Playgroud)
上面的代码只是执行使用exec dbo.spGetSomeData并使用dataRader读取所有结果并保存在dynamic对象中.如果您$.ajax打电话,api/My您将获得从中返回的数据dbo.spGetSomeData,您可以直接在JavaScript代码中使用.上面的代码非常透明.返回的数据集中的字段名称dbo.spGetSomeData将是JavaScript代码中属性的名称.您无需以任何方式管理C#代码中的任何实体类.您的C#代码没有从存储过程返回的字段名称.因此,如果您要扩展/更改dbo.spGetSomeData(重命名某些字段,添加新字段)的代码,则只需调整JavaScript代码,但不需要调整C#代码.
DbContext有一个Database属性,它保存与数据库的连接,您可以随意执行以下操作:
context.Database.SqlQuery<Foo>("exec [dbo].[GetFoo] @Bar = {0}", bar);
Run Code Online (Sandbox Code Playgroud)
但是,我建议您不要在Web Api操作中执行此操作,而是向您的上下文或与您的上下文交互的任何服务/存储库添加方法.然后在您的操作中调用此方法.理想情况下,您希望将所有SQL内容保存在一个位置.
| 归档时间: |
|
| 查看次数: |
17691 次 |
| 最近记录: |