【问题标题】:.NET Core associate multiple enteties to a user.NET Core 将多个实体关联到一个用户
【发布时间】:2020-01-12 17:26:01
【问题描述】:

我正在尝试将用户和班级之间的一对多关系关联起来。当我尝试创建帖子时,我也在尝试将其添加到用户模型中,但我似乎无法正确处理。

应该能够拥有多个项目实体的用户

public class AppUser : IdentityUser
{
    public ICollection<UserProject> Projects { get; set; }
}

项目模型

public class UserProject
{
    public int Id { get; set; }

    public string Name { get; set; }
}

添加项目并将其与用户关联的操作

    [HttpPost]
    [ValidateAntiForgeryToken]
    public async Task<IActionResult> Create(UserProject userProject)
    {

        if (ModelState.IsValid)
        {
            AppUser appUser = await userManager.GetUserAsync(HttpContext.User);
            appUser.Projects.Add(userProject);

            context.Projects.Add(userProject);
            await context.SaveChangesAsync();

            return RedirectToAction("Index");
        }
        return View(userProject);
    }

但是这个context.Projects.Add(userProject); 导致错误NullReferenceException: Object reference not set to an instance of an object. 有人请告诉我出了什么问题以及如何实现我想要做的事情吗?

数据库上下文

public class ScrumApplicationContext : IdentityDbContext<AppUser>
{
    public ScrumApplicationContext(DbContextOptions<ScrumApplicationContext> options)
        : base(options)
    {
    }
    public DbSet<UserProject> Projects { get; set; }

}

启动配置服务

    public Startup(IConfiguration configuration)
    {
        Configuration = configuration;
    }

    public IConfiguration Configuration { get; }

    // This method gets called by the runtime. Use this method to add services to the container.
    public void ConfigureServices(IServiceCollection services)
    {
        services.AddControllersWithViews();

        services.AddDbContext<ScrumApplicationContext>(options => options.UseSqlServer(Configuration.GetConnectionString("ScrumApplicationContext")));

        services.AddIdentity<AppUser, IdentityRole>()
            .AddEntityFrameworkStores<ScrumApplicationContext>()
            .AddDefaultTokenProviders();
    }

    // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
    public void Configure(IApplicationBuilder app, IWebHostEnvironment env, IServiceProvider serviceProvider)
    {
        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
        }
        else
        {
            app.UseExceptionHandler("/Home/Error");
            // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
            app.UseHsts();
        }
        app.UseHttpsRedirection();
        app.UseStaticFiles();

        app.UseRouting();

        app.UseAuthentication();
        app.UseAuthorization();

        app.UseEndpoints(endpoints =>
        {
            endpoints.MapControllerRoute(
                name: "areas",
                pattern: "{area:exists}/{controller=Home}/{action=Index}/{id?}"
            );

            endpoints.MapControllerRoute(
                name: "default",
                pattern: "{controller=Home}/{action=Index}/{id?}"
            );
        });
        CreateAdminRole(serviceProvider);
        CreateAdminUserAsync(serviceProvider);
    }

创建视图

@model ScrumApp.Models.UserProject

@{
    ViewData["Title"] = "Create";
}

<h1>Create</h1>

<div class="row">
    <div class="col-md-4">
        <form asp-action="Create">
            <div asp-validation-summary="ModelOnly" class="text-danger"></div>

            <div class="form-group">
                <label asp-for="Name" class="control-label"></label>
                <input asp-for="Name" class="form-control" />
                <span asp-validation-for="Name" class="text-danger"></span>
            </div>

            <div class="form-group">
                <input type="submit" value="Create" class="btn btn-primary" />
            </div>
        </form>
    </div>
</div>

<div>
    <a asp-action="Index">Back to List</a>
</div>

@section Scripts {
    @{await Html.RenderPartialAsync("_ValidationScriptsPartial");}
}

【问题讨论】:

  • 如何实例化上下文?你注入构造函数吗?如果是这样,您是否使用 AddDbConext 在 Startup 类中正确设置?
  • 是的,我在构造函数中注入了上下文,我认为我已经正确设置了所有内容,我将编辑帖子并查看 dbContext 类和 configureservices 方法。
  • 1.你能告诉我们你的创业公司吗? 2、public async Task&lt;IActionResult&gt; Create(UserProject userProject)这个action方法执行时,userProject是否为null?您能否向我们展示您的视图(表单)的代码? 3.当这一行“AppUser appUser = await userManager.GetUserAsync(HttpContext.User);”被执行了,appUser 是预期的结果吗?
  • 我已经添加了请求的文件以及问题 3,是的,appUser 是预期的结果。项目本身会创建,但不会添加到用户项目集合中。
  • userProject null 还是context.Projects null?或context?

标签: asp.net-mvc validation asp.net-core entity-relationship


【解决方案1】:

尝试将外键添加到UserProjectUserProject 类。

public class UserProject
{
    public int Id { get; set; }

    public string Name { get; set; }

    public int UserId { get; set; }
    public int ProjectId { get; set; }

    [ForeignKey("UserId")]
    public User User { get; set; }

    [ForeignKey("ProjectId")]
    public Project Project { get; set; }
}

然后你可以添加实体:

var userProject = new UserProject { UserId=.., ProjectId=.. };
context.UserProjects.Add(userProject);

【讨论】:

  • 我不认为这是问题所在。 “context.Projects.Add(userProject); 抛出 NullReferenceException”
  • 我在项目模型中添加了一个用户后,它就开始工作了,谢谢你们!
  • 这不是解决方案。
【解决方案2】:

问题是Projects 最初为空。您需要先对其进行初始化:

appUser.Projects ??= new List<UserProject>();
appUser.Projects.Add(userProject);

或者只是在属性上设置一个默认值:

public ICollection<UserProject> Projects { get; set; } = new List<UserProject>();

至少有一个项目(包括查询中的关系)可以解决该问题,因为 EF 已经实例化了该集合。但是,这并不能解决所有情况下的问题,也不是“解决方案”。您需要适当地计划和处理 null。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-09-20
    • 2019-10-20
    • 1970-01-01
    相关资源
    最近更新 更多