3

我收到一个例外:删除记录实体框架

无法更新EntitySet的“会话”,因为它有一个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

会话表是否有主键? – 2012-01-17 21:08:24

+0

@Klaus Byskov Hoffmann:不幸的是,它没有主键 – 14578446 2012-01-17 21:43:55

回答

1

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

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

+0

我在表格中有多个coulumns,符合PK条件,我可以看到这些在设计器中被标记为实体键。 User_id是其中的一个列,但我无法删除记录,并收到上述异常。 – 14578446 2012-01-18 14:42:24

1

该消息告诉问题是什么,只是不是很好。我会尽力详细说明。

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

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