Entity Framework 7 使用 .Net 中的现有数据库 5 MVC 6
Entity Framework 7 With Existing Database in .Net 5 MVC 6
您好,我在使用 Entity Framework 7 MVC 6 中从现有数据库中提取数据时遇到了一些问题。(我已经发布了项目代码 Here)。我已使用正确的连接字符串设置 appsettings.json:
"Data": {
"DefaultConnection": {
"ConnectionString": "Data Source=localhost;Initial Catalog=Demo;Integrated Security=True"
}
我有我的自定义上下文:
public class DatabaseContext : DbContext
{
public DbSet<User> Users { get; set; }
public DbSet<Customer> Customers { get; set; }
}
两个 Poco 类:
[Table("Customers")]
public class Customer
{
[Key]
public int Id { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public string Username { get; set; }
public string Password { get; set; }
public string EmailAddress { get; set; }
public DateTime Created { get; set; }
public DateTime Updated { get; set; }
public User User { get; set; }
public bool Active { get; set; }
}
[Table("Users")]
public class User
{
[Key]
public int Id { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public string Username { get; set; }
public string Password { get; set; }
public string EmailAddress { get; set; }
public DateTime Created { get; set; }
public DateTime Updated { get; set; }
public bool Active { get; set; }
}
我正在 startup.cs
中设置服务
public Startup(IHostingEnvironment env)
{
// Set up configuration sources.
var builder = new ConfigurationBuilder()
.AddJsonFile("appsettings.json")
.AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true);
if (env.IsDevelopment())
{
// For more details on using the user secret store see http://go.microsoft.com/fwlink/?LinkID=532709
builder.AddUserSecrets();
// This will push telemetry data through Application Insights pipeline faster, allowing you to view results immediately.
builder.AddApplicationInsightsSettings(developerMode: true);
}
builder.AddEnvironmentVariables();
Configuration = builder.Build();
}
public IConfigurationRoot Configuration { get; set; }
// 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.AddApplicationInsightsTelemetry(Configuration);
services.AddEntityFramework()
.AddSqlServer()
.AddDbContext<DatabaseContext>(options =>
options.UseSqlServer(Configuration["Data:DefaultConnection:ConnectionString"]));
services.AddIdentity<ApplicationUser, IdentityRole>()
.AddEntityFrameworkStores<ApplicationDbContext>()
.AddDefaultTokenProviders();
services.AddMvc();
// Add application services.
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
loggerFactory.AddConsole(Configuration.GetSection("Logging"));
loggerFactory.AddDebug();
app.UseApplicationInsightsRequestTelemetry();
if (env.IsDevelopment())
{
app.UseBrowserLink();
app.UseDeveloperExceptionPage();
app.UseDatabaseErrorPage();
}
else
{
app.UseExceptionHandler("/Home/Error");
// For more details on creating database during deployment see http://go.microsoft.com/fwlink/?LinkID=615859
try
{
using (var serviceScope = app.ApplicationServices.GetRequiredService<IServiceScopeFactory>()
.CreateScope())
{
serviceScope.ServiceProvider.GetService<ApplicationDbContext>()
.Database.Migrate();
}
}
catch { }
}
app.UseIISPlatformHandler(options => options.AuthenticationDescriptions.Clear());
app.UseApplicationInsightsExceptionTelemetry();
app.UseStaticFiles();
app.UseIdentity();
// To configure external authentication please see http://go.microsoft.com/fwlink/?LinkID=532715
app.UseMvc(routes =>
{
routes.MapRoute(
name: "default",
template: "{controller=Home}/{action=Index}/{id?}");
});
}
// Entry point for the application.
public static void Main(string[] args) => WebApplication.Run<Startup>(args);
}
我的用户控制器:
[Route("[controller]")]
public class UsersController : Controller
{
public DatabaseContext _context { get; set; }
public UsersController(DatabaseContext context)
{
_context = context;
}
[Route("[action]")]
public IActionResult Index()
{
using (_context)
{
List<User> users = _context.Users.ToList();
}
return View();
}
}
当我导航到 Users/index 页面时,列表行中不断出现以下错误:
$异常{"Object reference not set to an instance of an object."}System.NullReferenceException
出于某种原因,它没有从数据库中提取信息。我在 Microsoft SQLServer 2014 中创建它。并且在用户 table 中有数据。我是漏掉了一个步骤还是试图以错误的方式访问数据?
主要问题可以通过使用
来解决
public UsersController([FromServices] DatabaseContext context)
{
_context = context;
}
而不是
public UsersController(DatabaseContext context)
{
_context = context;
}
可以使用
[FromServices]
public DatabaseContext _context { get; set; }
但必须删除 构造函数public UsersController(DatabaseContext context)
。不推荐最后一种方式,因为RC2放弃了第二种方式。参见 the announcement。
以上更改解决了您遇到的第一个问题,但是您使用的数据库和测试数据又产生了一个问题,因为您的 Users
和 [=21= 的 Updated
字段] tables 包含 NULL
个值。因此你必须使用
public DateTime? Updated { get; set; }
而不是
public DateTime Updated { get; set; }
我推荐你的方式是commend
的用法
dnx ef dbcontext scaffold
"Data Source=localhost;Initial Catalog=Demo;Integrated Security=True"
EntityFramework.MicrosoftSqlServer --outputDir ..\Bestro\Model --verbose
您可以在主 project.json 存在的同一目录中执行(在 src\JenSolo
中)。为了更好地阅读,我将部分命令包装在新行中。一个人应该把所有的原因放在一起。上面的命令将创建 Users
和 Customers
classes 而不是 [Table("Users")]User
和 [Table("Customers")]Customer
,但是您可以使用代码作为基础并进行所有需要的修改稍后手动。
已更新: 在我看来,以下命令更符合脚手架的生成 classes:
dnx ef dbcontext scaffold
"Data Source=localhost;Initial Catalog=Demo;Integrated Security=True"
EntityFramework.MicrosoftSqlServer --outputDir ..\Bestro\Model --verbose
--targetProject Bestro --dataAnnotations
因为您在主项目 JenSolo 中使用了 Class Library Bestro。您应该从命令行以文件夹 ...\src\JenSolo
作为当前目录执行上述命令。它将在 Class 库项目 (Bestro) 中创建 Model
文件夹。 Model
文件夹将包含许多 *.cs
文件:每个数据库一个文件 table 和一个附加文件 DemoContext.cs
,其中包含 class DemoContext
派生自 DbContext
(Demo
是您使用的数据库的名称)。您应该从 DemoContext.cs
中删除 OnConfiguring
函数,以便能够通过
配置连接字符串
services.AddEntityFramework()
.AddSqlServer()
.AddDbContext<DemoContext>(options =>
options.UseSqlServer(Configuration["Data:DefaultConnection:ConnectionString"]));
in ConfigureServices
of Startup.cs
of the main project JenSolo
.
更新: 从 .NET Core RC2 开始应该使用 dotnet ef dbcontext scaffold 而不是 dnx ef dbcontext scaffold
.
您好,我在使用 Entity Framework 7 MVC 6 中从现有数据库中提取数据时遇到了一些问题。(我已经发布了项目代码 Here)。我已使用正确的连接字符串设置 appsettings.json:
"Data": {
"DefaultConnection": {
"ConnectionString": "Data Source=localhost;Initial Catalog=Demo;Integrated Security=True"
}
我有我的自定义上下文:
public class DatabaseContext : DbContext
{
public DbSet<User> Users { get; set; }
public DbSet<Customer> Customers { get; set; }
}
两个 Poco 类:
[Table("Customers")]
public class Customer
{
[Key]
public int Id { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public string Username { get; set; }
public string Password { get; set; }
public string EmailAddress { get; set; }
public DateTime Created { get; set; }
public DateTime Updated { get; set; }
public User User { get; set; }
public bool Active { get; set; }
}
[Table("Users")]
public class User
{
[Key]
public int Id { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public string Username { get; set; }
public string Password { get; set; }
public string EmailAddress { get; set; }
public DateTime Created { get; set; }
public DateTime Updated { get; set; }
public bool Active { get; set; }
}
我正在 startup.cs
中设置服务public Startup(IHostingEnvironment env)
{
// Set up configuration sources.
var builder = new ConfigurationBuilder()
.AddJsonFile("appsettings.json")
.AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true);
if (env.IsDevelopment())
{
// For more details on using the user secret store see http://go.microsoft.com/fwlink/?LinkID=532709
builder.AddUserSecrets();
// This will push telemetry data through Application Insights pipeline faster, allowing you to view results immediately.
builder.AddApplicationInsightsSettings(developerMode: true);
}
builder.AddEnvironmentVariables();
Configuration = builder.Build();
}
public IConfigurationRoot Configuration { get; set; }
// 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.AddApplicationInsightsTelemetry(Configuration);
services.AddEntityFramework()
.AddSqlServer()
.AddDbContext<DatabaseContext>(options =>
options.UseSqlServer(Configuration["Data:DefaultConnection:ConnectionString"]));
services.AddIdentity<ApplicationUser, IdentityRole>()
.AddEntityFrameworkStores<ApplicationDbContext>()
.AddDefaultTokenProviders();
services.AddMvc();
// Add application services.
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
loggerFactory.AddConsole(Configuration.GetSection("Logging"));
loggerFactory.AddDebug();
app.UseApplicationInsightsRequestTelemetry();
if (env.IsDevelopment())
{
app.UseBrowserLink();
app.UseDeveloperExceptionPage();
app.UseDatabaseErrorPage();
}
else
{
app.UseExceptionHandler("/Home/Error");
// For more details on creating database during deployment see http://go.microsoft.com/fwlink/?LinkID=615859
try
{
using (var serviceScope = app.ApplicationServices.GetRequiredService<IServiceScopeFactory>()
.CreateScope())
{
serviceScope.ServiceProvider.GetService<ApplicationDbContext>()
.Database.Migrate();
}
}
catch { }
}
app.UseIISPlatformHandler(options => options.AuthenticationDescriptions.Clear());
app.UseApplicationInsightsExceptionTelemetry();
app.UseStaticFiles();
app.UseIdentity();
// To configure external authentication please see http://go.microsoft.com/fwlink/?LinkID=532715
app.UseMvc(routes =>
{
routes.MapRoute(
name: "default",
template: "{controller=Home}/{action=Index}/{id?}");
});
}
// Entry point for the application.
public static void Main(string[] args) => WebApplication.Run<Startup>(args);
}
我的用户控制器:
[Route("[controller]")]
public class UsersController : Controller
{
public DatabaseContext _context { get; set; }
public UsersController(DatabaseContext context)
{
_context = context;
}
[Route("[action]")]
public IActionResult Index()
{
using (_context)
{
List<User> users = _context.Users.ToList();
}
return View();
}
}
当我导航到 Users/index 页面时,列表行中不断出现以下错误:
$异常{"Object reference not set to an instance of an object."}System.NullReferenceException
出于某种原因,它没有从数据库中提取信息。我在 Microsoft SQLServer 2014 中创建它。并且在用户 table 中有数据。我是漏掉了一个步骤还是试图以错误的方式访问数据?
主要问题可以通过使用
来解决public UsersController([FromServices] DatabaseContext context)
{
_context = context;
}
而不是
public UsersController(DatabaseContext context)
{
_context = context;
}
可以使用
[FromServices]
public DatabaseContext _context { get; set; }
但必须删除 构造函数public UsersController(DatabaseContext context)
。不推荐最后一种方式,因为RC2放弃了第二种方式。参见 the announcement。
以上更改解决了您遇到的第一个问题,但是您使用的数据库和测试数据又产生了一个问题,因为您的 Users
和 [=21= 的 Updated
字段] tables 包含 NULL
个值。因此你必须使用
public DateTime? Updated { get; set; }
而不是
public DateTime Updated { get; set; }
我推荐你的方式是commend
的用法dnx ef dbcontext scaffold
"Data Source=localhost;Initial Catalog=Demo;Integrated Security=True"
EntityFramework.MicrosoftSqlServer --outputDir ..\Bestro\Model --verbose
您可以在主 project.json 存在的同一目录中执行(在 src\JenSolo
中)。为了更好地阅读,我将部分命令包装在新行中。一个人应该把所有的原因放在一起。上面的命令将创建 Users
和 Customers
classes 而不是 [Table("Users")]User
和 [Table("Customers")]Customer
,但是您可以使用代码作为基础并进行所有需要的修改稍后手动。
已更新: 在我看来,以下命令更符合脚手架的生成 classes:
dnx ef dbcontext scaffold
"Data Source=localhost;Initial Catalog=Demo;Integrated Security=True"
EntityFramework.MicrosoftSqlServer --outputDir ..\Bestro\Model --verbose
--targetProject Bestro --dataAnnotations
因为您在主项目 JenSolo 中使用了 Class Library Bestro。您应该从命令行以文件夹 ...\src\JenSolo
作为当前目录执行上述命令。它将在 Class 库项目 (Bestro) 中创建 Model
文件夹。 Model
文件夹将包含许多 *.cs
文件:每个数据库一个文件 table 和一个附加文件 DemoContext.cs
,其中包含 class DemoContext
派生自 DbContext
(Demo
是您使用的数据库的名称)。您应该从 DemoContext.cs
中删除 OnConfiguring
函数,以便能够通过
services.AddEntityFramework()
.AddSqlServer()
.AddDbContext<DemoContext>(options =>
options.UseSqlServer(Configuration["Data:DefaultConnection:ConnectionString"]));
in ConfigureServices
of Startup.cs
of the main project JenSolo
.
更新: 从 .NET Core RC2 开始应该使用 dotnet ef dbcontext scaffold 而不是 dnx ef dbcontext scaffold
.