如何在EFCore中更新更复杂的对象?

时间:2019-12-18 09:43:45

标签: c# entity-framework asp.net-core entity-framework-core

我想在我的asp.net core 2项目中更新复杂的对象属性。

我的UserProjects类如下:

    public class UserProject
    {
        public int UserId { get; set; }
        public User User { get; set; }
        public int ProjectId { get; set; }
        public Project Project { get; set; }
    }

我要将项目状态从就绪更改为待定的方法。使用我知道的简单对象,但是使用复杂的对象,即使我将使用_context.Projects,也无法实现entry.ProjectStatus之类的参数。 我的方法如下:

        [HttpPost("changeprojectstatus/{userId}/{projectId}")]
        public IActionResult ChangeProjectStatus(int userId, int projectId)
        {
            var result = _context.UserProjects.Where(x => x.UserId == userId && x.ProjectId == 
                                                                          projectId);

            if (result != null)
            {
                // Make changes on entity
                var pr = result.Where(x => x.Project.Status == ProjectStatus.Ready);

                // Update entity in DbSet
                _context.Projects.Update(pr);
                _context.SaveChanges();
            }


            if (userId != int.Parse(User.FindFirst(ClaimTypes.NameIdentifier).Value))
                return Unauthorized();

            return Ok();
        }

3 个答案:

答案 0 :(得分:1)

您的错误在这里,您正在尝试使用Projects类更新UserProject。在结果查询中,您将返回UserObject

在更新时,您更新了Projects对象, 与您的UserProjects不同。

我看到了两种解决方案,请根据需要进行选择。

首先更新Projects对象

[HttpPost("changeprojectstatus/{userId}/{projectId}")]
        public IActionResult ChangeProjectStatus(int userId, int projectId)
        {
            var result = _context.UserProjects.First(x => x.UserId == userId && x.ProjectId == 
                                                                          projectId).Select(up => up.Project);

            if (result != null)
            {
                // Make changes on entity
                var pr = result.FirstOrDefault(x => x.Status == ProjectStatus.Ready);
                pr.Status = ProjectStatus.Pending; //update
                // Update entity in DbSet
                _context.Projects.Update(pr);
                _context.SaveChanges();
            }


            if (userId != int.Parse(User.FindFirst(ClaimTypes.NameIdentifier).Value))
                return Unauthorized();

            return Ok();
        }

第二次更新UserProjects对象

[HttpPost("changeprojectstatus/{userId}/{projectId}")]
        public IActionResult ChangeProjectStatus(int userId, int projectId)
        {
            var result = _context.UserProjects.First(x => x.UserId == userId && x.ProjectId == 
                                                                          projectId);

            if (result != null)
            {
                // Make changes on entity
                var pr = result.FirstOrDefault(x => x.Project.Status == ProjectStatus.Ready);
                pr.Peoject.Status = ProjectStatus.Pending; //update the status
                // Update entity in DbSet
                _context.UserProjects.Update(pr);
                _context.SaveChanges();
            }


            if (userId != int.Parse(User.FindFirst(ClaimTypes.NameIdentifier).Value))
                return Unauthorized();

            return Ok();
        }

答案 1 :(得分:1)

一些问题:

  1. 您从UserProjects而不是Projects的集合开始
  2. 在您的pr变量中您仍在创建UserProjects的集合,因为您正在运行where,而不是firstOrDefault
  3. 您正在尝试将UserProjects列表作为一种项目类型发送出去

首先确保PR是单一的,而不是集合。然后,如果UserProjects与Projects相同,则可以使用AutoMapper将USerProject映射到一种Project类型,然后进行更新。

这里的主要线索是在错误消息中,一种类型不能是另一种类型。

答案 2 :(得分:0)

将我的代码更改为Projects,现在可以正常工作: 代码如下:

[HttpPost("changeprojectstatus/{userId}/{projectId}")]
public IActionResult ChangeProjectStatus(int userId, int projectId)
{
    var project = _context.Projects.Where(x => x.Id == projectId);

    {
        // Make changes on entity
        var pr = project.FirstOrDefault(x => x.Status == ProjectStatus.Ready);
        pr.Status = ProjectStatus.Pending; //update the status
        // Update entity in DbSet
        _context.Projects.Update(pr);
        _context.SaveChanges();
    }

    if (userId != int.Parse(User.FindFirst(ClaimTypes.NameIdentifier).Value))
        return Unauthorized();

    return Ok();
}