保存子对象时使用ef6复制记录

时间:2017-05-29 14:08:00

标签: c# asp.net entity-framework entity-framework-6 asp.net-mvc-5

我有一个相当有趣的问题,我不太确定如何正确地通过它。为了完全理解我的问题,请记住以下内容:

我正在“塑造”我的功能。例如,我编写了一个“Logger”dll,然后将其转换为一个包。这个DLL有自己的DbContext,并且知道某些表的结果。然后我写了一个“Tracker”dll,它扩展了Logger dll。跟踪器dll是另一个具有自己的Db Context和自己的表的模块。它只知道Logger dll知道它的服务层及其模型层。让我告诉你看起来像什么:

以下是模型(代表表格)

//Logger Module
public class LogError : ILogError
{
    public Guid Id { get; set; }
    //more stuff not relavent to the problem
}

//Tracker Module
public class ErrorTicket : IErrorTicket
{
    public Guid Id { get; set; }
    public Guid LogErrorId { get; set; }
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int TicketNumber { get; set; }
    //More properties not related to the problem

    public virtual LogError LogError { get; set; }
    public virtual ILogError MyLogError => LogError;
    public virtual ICollection<ErrorTicketNote> ErrorTicketNotes { get; set; }
    public virtual IEnumerable<IErrorTicketNote> MyErrorTicketNotes => ErrorTicketNotes;
}

请记住ErroTicket类,我使用接口来暴露某些方法。例如,我的界面只有getter而没有setter,所以当传递一个接口时,该类无法更新。我宁愿不讨论为什么我这样做,因为我非常肯定它不是问题的一部分。只是想做一个不那么你理解为什么我有LogError然后在那里列出MyLogError。

现在我的DbContext有以下内容:

//Logger Module
public class LoggerDbContext : DbContext, ILoggerDbContext
{
    public DbSet<Model.LogError> LogError { get; set; }
    public DbSet<Model.LogInfo> LogInfo { get; set; }

    public IEnumerable<ILogError> LogErrors => LogError;
    public IEnumerable<ILogInfo> LogInfos => LogInfo;

    public LoggerDbContext(string connectionString = "DefaultConnection") : base(connectionString) { }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
        base.OnModelCreating(modelBuilder);
    }

    public void CreateLog(ILogError logError)
    {
        LogError.Add((Model.LogError) logError);
        SaveChanges();
    }

    public void CreateLog(ILogInfo logInfo)
    {
        LogInfo.Add((Model.LogInfo) logInfo);
        SaveChanges();
    }
}

//Tracker Module
public class TrackerDbContext : DbContext, ITrackerDbContext
{
    public DbSet<ErrorTicket> ErrorTicket { get; set; }
    public DbSet<ErrorTicketNote> ErrorTicketNote { get; set; }

    public IEnumerable<IErrorTicket> ErrorTickets => ErrorTicket;
    public IEnumerable<IErrorTicketNote> ErrorTicketNotes => ErrorTicketNote;

    public TrackerDbContext(string connectionString = "DefaultConnection") : base(connectionString) { }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
        base.OnModelCreating(modelBuilder);
    }

    public void CreateTicket(IErrorTicket errorTicket)
    {
        ErrorTicket.Add((ErrorTicket) errorTicket);
        SaveChanges();
    }

    public void ModifyTicket(IErrorTicket errorTicket)
    {
        Entry(errorTicket).State = EntityState.Modified;
        SaveChanges();
    }

    public void CreateTicketNote(IErrorTicketNote errorTicketNote)
    {
        ErrorTicketNote.Add((ErrorTicketNote) errorTicketNote);
        SaveChanges();
    }

    public void ModifyTicketNote(IErrorTicketNote errorTicketNote)
    {
        Entry(errorTicketNote).State = EntityState.Modified;
        SaveChanges();
    }
}

正如您所看到的,两个DbContext类彼此不了解,但通过我的模型,我创建了一个外键关系。现在我的问题。

发生错误时,我的代码运行如下:

//the line bellow calls a Logger service that ends up invoking the method from the Logger DbContext - public void CreateLog(ILogError logError)

var var logError = _databaseLoggerService.Error(exception, message);

//Then I try to create my ErrorTicket and I assign the logError object to the class to create the relation of the foreign key.
var currentTime = DateTime.Now;
var errorTicket = new ErrorTicket
{
    Id = Guid.NewGuid(),
    LogErrorId = logError.Id,
    TimeCreated = currentTime,
    TimeResolved = null,
    TimeOfFirstOccurrence = currentTime,
    TimeOfLastOccurrence = currentTime,
    TotalOccurrences = 1,
    Resolved = false,
    Resolution = string.Empty,
    CommitNumber = string.Empty,
    TimeImplemented = null,
    LogError = (LogError) logError
};

_trackerDbContext.CreateTicket(errorTicket);

我得到的问题如下:

  

违反PRIMARY KEY约束'PK_dbo.LogError'。无法在对象'dbo.LogError'中插入重复键。重复键值为(769fb127-a8d8-40de-9492-fc61ca86cb16)。   声明已经终止。

如果我查看我的LogError表,那么该键确实存在一条记录。我假设它是在我调用_databaseLoggerService.Error(exception, message);

时创建的

我不明白,为什么这是EF6的问题或者如何通过它?

我已经对这个主题做了很多研究,我发现文章说明了因为它是2个sebarate DbContextes,所以第二个可能不知道该记录存在所以它当我caled .Add方法时,它标记了所有对象对于insertoin并因此生成INSERT查询。这是有道理的,我可以简单地不调用我的数据库创建,让我的跟踪器只为我创建两个对象。哪个都很好,但是,我遇到的问题是当我尝试修改'记录时,我得到完全相同的问题。即使我将记录标记为修改,它也会生成插入查询。

我的问题是如何解决这个问题?

0 个答案:

没有答案