我在TicketsTags之间有很多关系,并且可以将标签添加到票证中而不会出现问题。但是,我无法从故障单中更新/删除标签。

测试

[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);输出的SQL

DELETE [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/

10-13 08:07
查看更多