我在Tickets
和Tags
之间有很多关系,并且可以将标签添加到票证中而不会出现问题。但是,我无法从故障单中更新/删除标签。
测试
[TestMethod]
public void TagRepository_UpdateTicketWithTwoTagsToNone_TicketHasZeroTag()
{
// Arrange
var ticketId = new Guid("54E86203-71F9-E411-80E5-000C29193DF7");
var selectedTags = "";
using (var context = new TicketModelContext())
{
using (new TransactionScope())
{
var ticketToUpdate = context.Tickets.Include(t=>t.Tags).First(t => t.TicketId == ticketId);
Assert.AreEqual(0, ticketToUpdate.Tags.Count);
ticketToUpdate.Tags.Add(context.Tags.Find(new Guid("D1757675-A06C-4C1F-9DAD-03EE00BB1100")));
ticketToUpdate.Tags.Add(context.Tags.Find(new Guid("96C66A97-9C3E-4B15-BD70-A4C832EEDE8B")));
context.SaveChanges();
var setupTicket = context.Tickets.Single(t => t.TicketId == ticketId);
Assert.AreEqual(2, setupTicket.Tags.Count);
// Act
new TagRepository().UpdateTicketTags(ticketId, selectedTags);
// Assert
var updatedTeicket = context.Tickets.Include(t => t.Tags).First(t => t.TicketId == ticketId);
Assert.AreEqual(0, updatedTeicket.Tags.Count);
// HERE I EXPECT 0 BUT GET 2
}
}
}
储存库方法
public void UpdateTicketTags(Guid ticketId, string selectedTags)
{
var tags = new List<Tag>();
using (var context = new TicketModelContext())
{
if (!String.IsNullOrEmpty(selectedTags))
{
foreach (var selectedTag in selectedTags.Split(','))
{
tags.Add(context.Tags.Find(new Guid(selectedTag)));
}
}
var ticketToUpdateTags = context.Tickets.Find(ticketId);
context.Entry(ticketToUpdateTags).Collection(t => t.Tags).Load();
ticketToUpdateTags.Tags = tags; // I EXPECT TAGS TO BE EMPTY IN THIS TEST
context.SaveChanges();
}
}
命令
context.Database.Log = s => System.Diagnostics.Debug.WriteLine(s);
输出的SQLDELETE [dbo].[TagTickets]
WHERE (([Tag_TagId] = @0) AND ([Ticket_TicketId] = @1))
-- @0: '96c66a97-9c3e-4b15-bd70-a4c832eede8b' (Type = Guid)
-- @1: '54e86203-71f9-e411-80e5-000c29193df7' (Type = Guid)
-- Executing at 26/05/2015 13:16:39 +01:00
-- Completed in 24 ms with result: 1
DELETE [dbo].[TagTickets]
WHERE (([Tag_TagId] = @0) AND ([Ticket_TicketId] = @1))
-- @0: 'd1757675-a06c-4c1f-9dad-03ee00bb1100' (Type = Guid)
-- @1: '54e86203-71f9-e411-80e5-000c29193df7' (Type = Guid)
-- Executing at 26/05/2015 13:16:39 +01:00
-- Completed in 21 ms with result: 1
我花了几个小时尝试使用不同的测试来测试不同的代码变体,并且所有结果都相同。任何帮助将非常感激!
最佳答案
基本上,您的测试无法正常工作的原因是因为未反映在Entity Framework中因不同上下文而发生的更改。即使使用了TransactionScope,如果在内部上下文(发生在UpdateTicketTags()中)调用SaveChanges(),那么这些更改也不会反映在外部上下文中。
我通常更喜欢将动作分解为较小的块,而不是一个较长的上下文,这样
它模拟了现实操作在您的应用程序中的发生方式(例如,如果这是一个ASP.NET MVC应用程序,则多个控制器正在处理可能会或可能不会修改同一表的多个请求),并且
它为我提供了每个对象的最新信息。
[TestMethod]
public void TagRepository_UpdateTicketWithTwoTagsToNone_TicketHasZeroTag()
{
// Arrange
var ticketId = new Guid("54E86203-71F9-E411-80E5-000C29193DF7");
var selectedTags = "";
using (var context = new TicketModelContext())
{
var ticketToUpdate = context.Tickets.Include(t=>t.Tags).First(t => t.TicketId == ticketId);
Assert.AreEqual(0, ticketToUpdate.Tags.Count);
ticketToUpdate.Tags.Add(context.Tags.Find(new Guid("D1757675-A06C-4C1F-9DAD-03EE00BB1100")));
ticketToUpdate.Tags.Add(context.Tags.Find(new Guid("96C66A97-9C3E-4B15-BD70-A4C832EEDE8B")));
context.SaveChanges();
var setupTicket = context.Tickets.Single(t => t.TicketId == ticketId);
Assert.AreEqual(2, setupTicket.Tags.Count);
}
// Act
new TagRepository().UpdateTicketTags(ticketId, selectedTags);
using (var context = new TicketModelContext())
{
// Assert
var updatedTeicket = context.Tickets.Include(t => t.Tags).First(t => t.TicketId == ticketId);
Assert.AreEqual(0, updatedTeicket.Tags.Count);
}
}
关于c# - 代码优先 Entity Framework 无法更新许多相关实体,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/30456876/