实体框架 7 与 .Net 5 中的现有数据库 MVC 6.

本文关键字:数据库 MVC 框架 Net 实体 | 更新日期: 2023-09-27 18:28:33

嗨,我在使用实体框架 7 MVC 6 中从现有数据库中提取数据时遇到一些问题。(我已经在这里发布了项目代码(。我已经使用正确的连接字符串设置了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; }
}

我正在启动中设置服务.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();
    }
}

当我导航到用户/索引页面时,我在列表行上不断收到以下错误:

$exception {"对象引用未设置为对象的实例。 System.NullReferenceException

由于某种原因,它不会从数据库中提取信息。我在 Microsoft SQLServer 2014 中创建它。并且用户表中有数据。我是否错过了步骤或我是否尝试以错误的方式访问数据?

实体框架 7 与 .Net 5 中的现有数据库 MVC 6.

主要问题可以通过使用

public UsersController([FromServices] DatabaseContext context)
{
    _context = context;
}

而不是

public UsersController(DatabaseContext context)
{
    _context = context;
}

可以使用

[FromServices]
public DatabaseContext _context { get; set; }

但是必须删除构造函数public UsersController(DatabaseContext context).不建议使用最后一种方法,因为 RC2 放弃了第二种方式。请参阅公告。

上述更改解决了您遇到的第一个问题,但是您使用的数据库和测试数据又产生了一个问题,因为Users表和Customers表的Updated字段包含NULL值。因此,您必须使用

public DateTime? Updated { get; set; }

而不是

public DateTime Updated { get; set; }

我推荐你的方式是使用推荐

dnx ef dbcontext scaffold
    "Data Source=localhost;Initial Catalog=Demo;Integrated Security=True"
    EntityFramework.MicrosoftSqlServer --outputDir ..'Bestro'Model --verbose

您可以在主 project.json 所在的同一目录中执行(在 src'JenSolo 中(。我将命令的部分包装在新行上以便更好地阅读。一个人应该把所有的东西都放在一条原因线上。上面的命令将创建UsersCustomers类,而不是[Table("Users")]User[Table("Customers")]Customer,但您可以使用代码作为基础,并在以后手动进行所有必需的修改。

更新:在我看来,以下命令更好地对应于脚手架类的生成:

dnx ef dbcontext scaffold
    "Data Source=localhost;Initial Catalog=Demo;Integrated Security=True"
    EntityFramework.MicrosoftSqlServer --outputDir ..'Bestro'Model --verbose
    --targetProject Bestro --dataAnnotations

因为你在主项目JenSolo中使用了类库Bestro。您应该从命令行执行上述命令,并将文件夹...'src'JenSolo作为当前目录。它将在类库项目 (Bestro( 中创建Model文件夹。Model文件夹将包含许多*.cs文件:每个数据库表一个文件和一个附加文件DemoContext.cs,其中包含派生自DbContext的类DemoContext(Demo是您使用的数据库的名称(。应从DemoContext.cs中删除OnConfiguring函数,以便能够通过以下方式配置连接字符串

services.AddEntityFramework()
   .AddSqlServer()
   .AddDbContext<DemoContext>(options =>
      options.UseSqlServer(Configuration["Data:DefaultConnection:ConnectionString"]));

ConfigureServices Startup.cs的主要项目JenSolo.

更新:从.NET Core RC2开始,应该使用dotnet ef dbcontext scaffold而不是dnx ef dbcontext scaffold