如何在同一路由控制器中使用和删除

发布于 2025-02-13 00:22:35 字数 1102 浏览 1 评论 0原文

我可以在同一路由控制器中添加和删除实体吗?我尝试了这种方法,添加了作品,但删除实体给了我一个错误。

[HttpPost]
public async Task<ActionResult<Upvote>> AddRemoveUpvote(CreateUpvoteDTO upvoteDtO)
{
    if (_context.Upvotes == null)
    {
        return Problem("Entity set 'ApplicationDbContext.Upvotes'  is null.");
    }
    var upvote = _mapper.Map<Upvote>(upvoteDtO);
    foreach (var item in _context.Upvotes)
    {
        if (item.UserId == upvote.UserId)
        {
            _context.Upvotes.Remove(item);
            await _context.SaveChangesAsync();
            return Ok("Topic unliked");
        }
    }
    _context.Upvotes.Add(upvote);
    await _context.SaveChangesAsync();
    
    return Ok("Topic Liked");
}

这是试图删除的错误:

system.invalidoperationException:已经有一个与此连接关联的开放数据标准,必须首先关闭。 在Microsoft.data.sqlclient.sqlineternconnectiontds.validateconnectionforeforexecute(sqlcommand命令) 在microsoft.data.sqlclient.sqlineternconnection.beginsqltransaction(iNALATIONLEVEL ISO,字符串TransActionName,boolean shordReconnect)

Is there a way I can add and remove entities in the same route controller? I tried this method, adding works but removing the entity gave me an error.

[HttpPost]
public async Task<ActionResult<Upvote>> AddRemoveUpvote(CreateUpvoteDTO upvoteDtO)
{
    if (_context.Upvotes == null)
    {
        return Problem("Entity set 'ApplicationDbContext.Upvotes'  is null.");
    }
    var upvote = _mapper.Map<Upvote>(upvoteDtO);
    foreach (var item in _context.Upvotes)
    {
        if (item.UserId == upvote.UserId)
        {
            _context.Upvotes.Remove(item);
            await _context.SaveChangesAsync();
            return Ok("Topic unliked");
        }
    }
    _context.Upvotes.Add(upvote);
    await _context.SaveChangesAsync();
    
    return Ok("Topic Liked");
}

Here is the error while trying to remove:

System.InvalidOperationException: There is already an open DataReader associated with this Connection which must be closed first.
at Microsoft.Data.SqlClient.SqlInternalConnectionTds.ValidateConnectionForExecute(SqlCommand command)
at Microsoft.Data.SqlClient.SqlInternalConnection.BeginSqlTransaction(IsolationLevel iso, String transactionName, Boolean shouldReconnect)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

溺ぐ爱和你が 2025-02-20 00:22:35

您会遇到该错误,因为您仍在尝试保存更改时upvotes dbset。实体框架DBContext使用与数据库的单个连接。我看到的第二个问题是,您在upvotes dbset中的每个呼叫中​​的每个记录中都循环循环。这是效率低下的,随着时间的流逝,随着更多记录添加到该表中,随着时间的流逝,这会变得越来越慢。而是让EF仅将值过滤到相关记录。

您的代码的整洁版本看起来像这样:

// See if an existing upvote exists...
var existingUpvote = await _context.Upvotes
    .Where(uv => uv.UserId == upvote.UserId)
    .SingleOrDefaultAsync();

// If it exists, then remove it
if(existingUpvote != null)
{
    _context.Upvotes.Remove(item);
    await _context.SaveChangesAsync();
    return Ok("Topic unlike");
}

// since we reached here there was no existing vote so we can add a new one
_context.Upvotes.Add(upvote);
await _context.SaveChangesAsync();

return Ok("Topic Liked");

此外,我怀疑您还缺少对该主题的支票,因此您的条款可能看起来更像是这样:

var existingUpvote = await _context.Upvotes
    .Where(uv => uv.UserId == upvote.UserId && uv.TopicId == upvote.TopicId)
    .SingleOrDefaultAsync();

You are getting that error because you are still looping over the Upvotes DbSet while trying to save changes. An Entity Framework DbContext uses a single connection to the database. The second problem I see is that you are looping over every single record in the Upvotes DbSet on every call to this API endpoint. That is massively inefficient and will get slower and slower over time as more records are added to that table. Instead, get EF to filter the values to the relevant records only.

A much tidier version of your code would look like this:

// See if an existing upvote exists...
var existingUpvote = await _context.Upvotes
    .Where(uv => uv.UserId == upvote.UserId)
    .SingleOrDefaultAsync();

// If it exists, then remove it
if(existingUpvote != null)
{
    _context.Upvotes.Remove(item);
    await _context.SaveChangesAsync();
    return Ok("Topic unlike");
}

// since we reached here there was no existing vote so we can add a new one
_context.Upvotes.Add(upvote);
await _context.SaveChangesAsync();

return Ok("Topic Liked");

Additionally, I suspect you are also missing a check for the topic so your where clause should probably look more like this:

var existingUpvote = await _context.Upvotes
    .Where(uv => uv.UserId == upvote.UserId && uv.TopicId == upvote.TopicId)
    .SingleOrDefaultAsync();
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文