嗨,我在使用实体框架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();
    }
}


导航到“用户/索引”页面时,我在“列表”行上始终收到以下错误:

$ 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放弃了第二种方法。请参见the announcement

上面的更改解决了您遇到的第一个问题,但是您使用的数据库和测试数据又产生了一个问题,因为UpdatedUsers表的Customers字段包含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是数据库的名称,您可以使用)。您应该从OnConfiguring中删除​​DemoContext.cs函数,以便能够通过以下方式配置连接字符串

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


在主项目ConfigureServicesStartup.csJenSolo中。

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

关于c# - NET 7中具有现有数据库的 Entity Framework 7,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/34550846/

10-11 01:23
查看更多