我有一个相当有趣的问题,我不太确定如何正确地通过它。为了完全理解我的问题,请记住以下内容:
我正在“塑造”我的功能。例如,我编写了一个“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查询。这是有道理的,我可以简单地不调用我的数据库创建,让我的跟踪器只为我创建两个对象。哪个都很好,但是,我遇到的问题是当我尝试修改'记录时,我得到完全相同的问题。即使我将记录标记为修改,它也会生成插入查询。
我的问题是如何解决这个问题?