實體框架7與.Net 5 MVC 6中的現有數據庫

asp.net-core-mvc c# entity-framework-core

嗨,我在使用Entity Framework 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; }
}

我正在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();
    }
}

當我導航到用戶/索引頁面時,我在列表行上不斷收到以下錯誤:

$ exception {“對象引用未設置為對象的實例。”} System.NullReferenceException

由於某種原因,它不是從數據庫中提取信息。我在Microsoft SQLServer 2014中創建它。並且users表中有數據。我錯過了一步還是我試圖以錯誤的方式訪問數據?

一般承認的答案

主要問題可以通過使用來解決

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

代替

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

它可以使用

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

但是必須刪除構造函數public UsersController(DatabaseContext context) 。不推薦最後一種方式,因為RC2第二種方式掉線了。看公告

上述更改修復了您遇到的第一個問題,但您使用的數據庫和測試數據又產生了一個問題,因為您的UsersCustomers表的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 ,其中包含的類DemoContext衍生DbContextDemo是數據庫,您使用的名稱)。您應該從DemoContext.cs刪除OnConfiguring函數,以便能夠通過配置連接字符串

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

在主項目JenSoloStartup.csConfigureServices中。

更新:從.NET Core RC2開始,應該使用dotnet ef dbcontext scaffold而不是dnx ef dbcontext scaffold



許可下: CC-BY-SA with attribution
不隸屬於 Stack Overflow
這個KB合法嗎? 是的,了解原因
許可下: CC-BY-SA with attribution
不隸屬於 Stack Overflow
這個KB合法嗎? 是的,了解原因