【问题标题】:Unable to delete record from database Entity Framework C#无法从数据库实体框架 C# 中删除记录
【发布时间】:2018-04-21 00:26:53
【问题描述】:

自从向我的 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) { }
        }
}

当 delete 方法是这样时,没有调用异常,但它仍然不起作用。

我把删除方法改成这样了:

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 约束“FK_dbo.Logs_dbo.Users_User_ApiKey”冲突。冲突发生在数据库“SecuroteckWebApplication.Models.UserContext”、表“dbo.Logs”、列“userAPIKey”中。该语句已终止。

【问题讨论】:

  • @Kell 它似乎没有意识到这一点

标签: c# entity-framework


【解决方案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();
    }
}

【讨论】:

    【解决方案2】:

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

    看到您的实体代码,如果您首先使用实体​​框架代码,我不知道为什么首先创建外键。如果这是您的情况,那么您可能落入了实体框架约定规则。

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

    如果您使用的是 EF 代码优先。删除所有指向已删除用户的日志,或将它们更新为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() { }
    }
    

    对于强关系,如果没有配置级联约定,在删除用户之前应该删除日志或设置为空。

    【讨论】:

    • 我认为添加日志时可能有问题。我一直在逐步将日志添加到用户的位置,并且它看起来正在添加到集合中。但是,当单步执行删除方法时,用户日志始终为空!
    • 您使用的是 EF 代码优先还是 EF 数据库优先?此类问题的处理方法完全不同,因此请告诉我们您实际使用的是什么。
    • EF 代码优先。
    • 看一下编辑,可能你正在运行一个问题,因为一些缺乏定义。您还应该考虑是否要在删除User 后保留Logs,这取决于您的应用程序可能是正确的做法,但是LogUser 之间的关系可能不是很好主意。您可以删除关系并简单地添加一个不相关的Log 实体。如果外键不是可行的方法,那么在实体框架中定义关系不是一个好主意。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-08-03
    • 1970-01-01
    • 2013-07-17
    • 1970-01-01
    • 2018-01-14
    • 1970-01-01
    相关资源
    最近更新 更多