3

我收到一个例外:

无法更新 EntitySet 'Session',因为它有一个 DefiningQuery 并且元素中不存在支持当前操作的元素。

在尝试从数据库表中删除一行时。SaveChanges()调用存在的行时出现异常。下面是我的代码:

public static Func<DC21GPDEntities, string, IQueryable<Session>> compiledDeleteQuery =
    CompiledQuery.Compile((DC21GPDEntities ctx, string userId) =>
        (from rows in ctx.Sessions
         where rows.User_ID == userId
         select rows));

[HttpPost]
public ActionResult Index(string searchItem )
{
   try
   {
      string userId =searchItem.Trim();
      string successMessage 
                = "The session for User ID: " + userId + " has been cleared in Fascor.";

      dc21gpdContext.CommandTimeout = 180;

      Models.Session session = Queries.compiledDeleteQuery(dc21gpdContext, userId).FirstOrDefault();

      if (session == null)
          successMessage = "Session for User ID: " + userId + " does noe exist";
      else
      {
          dc21gpdContext.DeleteObject(session);
          dc21gpdContext.SaveChanges();
      }

      ViewData["SuccessMessage"] = successMessage;
      return View();
  }
  catch (Exception ex)
  {
     ViewData["SuccessMessage"] = "Failed to clear session";
     return View();
  }
}
4

2 回答 2

1

该消息正在说明问题所在,但不是很好。我会尝试详细说明。

默认情况下,实体框架会生成用于获取对象的查询。您的“会话”对象的 EntityContainer 具有显式查询,这意味着您的 EntityFramework 已被告知使用特定的手写 sql(或存储的过程)来获取会话。

当您覆盖该行为时,您还必须提供一个查询来告诉它如何删除会话。这是有关如何将此类删除功能添加到实体框架容器的文档。

于 2012-01-17T21:12:02.010 回答
1

如果您的Session表没有主键,则将其映射为DefiningQuery只读。DefinedQuery除非您创建定义这些操作的存储过程并将它们映射到模型中,否则您无法删除、插入或更新映射到的记录。

即使在那之后,它也不一定足够。实体通过它们的键被删除。您可以在实体模型中定义键,但键必须唯一标识记录。默认情况下,EF 将使用所有不可为空的非二进制列作为键。如果这组列不能唯一标识记录,则使用Session实体会遇到更多问题(例如,删除操作将删除多个记录并且SaveChanges会失败)-在这种情况下,唯一的选择是向表中添加唯一列并将其用作钥匙。一旦您将 PK 添加到表中,所有这些问题都将得到解决。

于 2012-01-18T11:24:13.923 回答