无法从数据库实体框架C#中删除记录

时间:2018-04-20 14:35:42

标签: c# entity-framework

自从向我的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;中。声明已经终止。

2 个答案:

答案 0 :(得分:1)

从SQL Server返回此错误。如上所述,您无法删除用户,因为dbo.Logs表中有与已删除用户相关的记录,并且定义了一个外键,将userAPIKey列与此已删除的用户相关联。

如果您正在使用Entity Framework Code First,那么看到您的实体代码,我无法说明为什么首先创建了外键。如果是这种情况,可能您正陷入实体框架约定规则。

无论如何,有一些方法可以解决这个问题。

如果您使用的是EF Code First 。删除指向已删除用户的所有日志或更新它们,将其设置为NULL,具体取决于您为已删除用户保留日志所需的数量。

编辑:由于OP使用的是Code First,因此LogUser之间的关系尚未完全定义。如果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();
    }
}