删除记录实体框架

时间:2012-01-17 21:05:30

标签: entity-framework c#-4.0 linq-to-entities asp.net-4.0 compiled-query

我收到一个例外:

  

无法更新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();
  }
}

2 个答案:

答案 0 :(得分:1)

消息告诉我们问题是什么,只是不太好。我会试着详细说明。

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

当您覆盖该行为时,您还必须提供一个查询,告诉它如何删除会话。 Here is the documentation关于如何将这样的删除功能添加到您的实体框架容器中。

答案 1 :(得分:1)

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

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