C# 使用另一个字段在ASP.Net Core controller中编辑操作

C# 使用另一个字段在ASP.Net Core controller中编辑操作,c#,asp.net-core-mvc,entity-framework-core,asp.net-core-2.0,C#,Asp.net Core Mvc,Entity Framework Core,Asp.net Core 2.0,我在我的表格中为每门课程都有一个URL字段。我用它作为路线参数。我这样做是为了让URL更加友好,据我所知,这也可能对我的SEO有所帮助(如果我错了,请纠正我)。使用例如设置,我无法确定如何创建编辑/删除操作 Course.cs:课程的模式 public partial class Course { public int Id { get; set; } public string Title { get; set; } // This is set as Unique K

我在我的表格中为每门课程都有一个URL字段。我用它作为路线参数。我这样做是为了让URL更加友好,据我所知,这也可能对我的SEO有所帮助(如果我错了,请纠正我)。使用例如设置,我无法确定如何创建编辑/删除操作

Course.cs:课程的模式

public partial class Course
{
    public int Id { get; set; }
    public string Title { get; set; }
    // This is set as Unique Key in the table. 
    public string Url { get; set; }
    public string InnerHtml { get; set; }
}
CourseController.cs:控制器和编辑操作供我们参考

    [HttpPost("Edit/{courseUrl}")]
    [ValidateAntiForgeryToken]
    [Authorize(Roles = "Administrator")]
    public async Task<IActionResult> Edit(string courseUrl, [Bind("Id,Title,Url,InnerHtml")] Course course)
    {

        var OriginalCourse = await _context.Courses.SingleOrDefaultAsync(m => m.Url == courseUrl);

        if (OriginalCourse.Id != course.Id)
        {
            return NotFound();
        }

        if (ModelState.IsValid)
        {
            try
            {
                _context.Update(course);
                await _context.SaveChangesAsync();
            }
            catch (DbUpdateConcurrencyException)
            {
                if (!CourseExists(course.Url))
                {
                    return NotFound();
                }
                else
                {
                    throw;
                }
            }
            return RedirectToAction(nameof(Index));
        }
        return View(course);
    }

处理这种情况的正确方法是什么?

正如错误消息所解释的,已经有一个从搜索加载的模型正在被ORM跟踪。如果要保存所需的特性,则需要将其复制到跟踪模型

//...code removed for brevity

var OriginalCourse = await _context.Courses.SingleOrDefaultAsync(m => m.Url == courseUrl);

if (OriginalCourse.Id != course.Id) {
    return NotFound();
}

if (ModelState.IsValid) {
    try {
        Populate(OriginalCourse, course);

        _context.Update(OriginalCourse);
        await _context.SaveChangesAsync();
    } catch (DbUpdateConcurrencyException) {
        if (!CourseExists(course.Url)) {
            return NotFound();
        } else {
            throw;
        }
    }
    return RedirectToAction(nameof(Index));
}

//...code removed for brevity
其中,
填充
可能如下所示

void Populate(Course original, Cource source) {
    original.Title = source.Title;
    original.Url = source.Url;
    original.InnerHtml = source.InnerHtml;
}
另一个选项是不从上下文中选择/返回项目,从而不加载实例

//...code removed for brevity

var exists = await _context.Courses.AnyAsync(m => m.Url == courseUrl);

if (!exists) {
    return NotFound();
}

//...code removed for brevity

然后更新提供的课程

我更喜欢第二个选项,因为它简明易懂。请尝试在查询中的SingleOrDefaultAsync之前添加AsNoTracking()。它将阻止更改跟踪器跟踪您仅用于验证Id的实体。
//...code removed for brevity

var exists = await _context.Courses.AnyAsync(m => m.Url == courseUrl);

if (!exists) {
    return NotFound();
}

//...code removed for brevity