自从向我的Entity Framework项目添加日志记录功能以来,我一直无法从表中删除任何记录。
以下是添加到数据库的对象的数据类,用户表的用户以及日志表的日志:
public class User
{
public string UserName { get; set; }
[Key]
public string ApiKey { get; set; } //unique database key and API key for user
public ICollection<Log> Logs { get; set; }
public User() { }
}
public class Log
{
[Key]
public int logID { get; set; }
public string logString { get; set; }
public string logDateTime { get; set; }
public string userAPIKey { get; set; }
public Log() { }
}
以下是将日志添加到表中的方式,因为自添加日志记录以来我一直遇到此问题:
public void addLogToUserWithApiKey(string logMessage, string apiKey)
{
Log newLog = new Log();
newLog.logID = makeLogID();
newLog.logString = logMessage;
newLog.logDateTime = DateTime.Now.ToShortDateString() + " " + DateTime.Now.ToString("h:mm:ss tt");
newLog.userAPIKey = apiKey;
using (var context = new UserContext())
{
User logUser = checkIfUserExistsWithApiKeyandReturnUser(apiKey);
if (logUser.Logs == null)
{
logUser.Logs = new Collection<Log>();
}
logUser.Logs.Add(newLog);
context.Logs.Add(newLog);
context.SaveChanges();
}
}
最后,这是删除记录的代码:
public void deleteUserFromDatabase(string mApiKey)
{
using (var context = new UserContext())
{
try
{
User userToDelete = checkIfUserExistsWithApiKeyandReturnUser(mApiKey);
if (userToDelete != null)
{
context.Users.Attach(userToDelete);
context.Users.Remove(userToDelete);
context.SaveChanges();
}
}
catch (Exception e) { }
}
}
当删除方法与此类似时,没有异常被调用,但它仍然无法正常工作。
我将删除方法更改为:
User userToDelete = checkIfUserExistsWithApiKeyandReturnUser(mApiKey);
if (userToDelete != null)
{
if (userToDelete.Logs != null)
{
userToDelete.Logs.ToList().ForEach(log => userToDelete.Logs.Remove(log));
}
context.Users.Attach(userToDelete);
context.Users.Remove(userToDelete);
context.SaveChanges();
}
我收到此错误消息:
DELETE语句与REFERENCE约束冲突&#34; FK_dbo.Logs_dbo.Users_User_ApiKey&#34;。冲突发生在数据库&#34; SecuroteckWebApplication.Models.UserContext&#34;,table&#34; dbo.Logs&#34;,column&#39; userAPIKey&#39;中。声明已经终止。
答案 0 :(得分:1)
从SQL Server返回此错误。如上所述,您无法删除用户,因为dbo.Logs
表中有与已删除用户相关的记录,并且定义了一个外键,将userAPIKey
列与此已删除的用户相关联。
如果您正在使用Entity Framework Code First,那么看到您的实体代码,我无法说明为什么首先创建了外键。如果是这种情况,可能您正陷入实体框架约定规则。
无论如何,有一些方法可以解决这个问题。
如果您使用的是EF Code First 。删除指向已删除用户的所有日志或更新它们,将其设置为NULL
,具体取决于您为已删除用户保留日志所需的数量。
编辑:由于OP使用的是Code First,因此Log
和User
之间的关系尚未完全定义。如果OP的目标是强关系,那么这是正确的实体代码。
public class User
{
public string UserName { get; set; }
[Key]
public string ApiKey { get; set; } //unique database key and API key for user
[InverseProperty("User")]
public virtual ICollection<Log> Logs { get; set; }
public User() { }
}
public class Log
{
[Key]
public int logID { get; set; }
public string logString { get; set; }
public string logDateTime { get; set; }
public string userAPIKey { get; set; }
[ForeignKey("userAPIKey")
public virtual User User {get; set; }
public Log() { }
}
如果没有配置级联约定,那么在强关系之前,应该删除日志或将其设置为null,然后才能删除用户。
答案 1 :(得分:1)
如果要删除User
,则必须先删除与该用户关联的所有Log
条目。
var apiKey = String.Empty; // The id of the user you want to delete
using (var context = new UserContext())
{
User userToDelete = checkIfUserExistsWithApiKeyandReturnUser(apiKey);
if (userToDelete != null)
{
var userLogs = context.Logs.Where(l => l.userAPIKey == apiKey);
if (userLogs.Any())
{
context.Logs.RemoveRange(userLogs);
}
context.Users.Attach(userToDelete);
context.Users.Remove(userToDelete);
context.SaveChanges();
}
}