Entity Framework 7在内存数据库异常中

时间:2016-01-20 17:01:10

标签: c# entity-framework-core

使用内存数据库进行EF 7单元测试时出现问题。以下应用程序将演示此问题。

using System;
using Microsoft.Data.Entity;
using Microsoft.Data.Entity.Infrastructure;

namespace EF7InMemoryBug
{
    public class Program
    {
        public static void Main(string[] args)
        {
            Program p = new Program();

            MembershipContext m1 = p.GetNewContext();
            MembershipContext m2 = p.GetNewContext();

            foreach (var member in m1.Members)
            {
                Console.WriteLine(member);
            }
        }

        private MembershipContext GetNewContext()
        {
            var optionsBuilder =
                new DbContextOptionsBuilder<MembershipContext>();
            optionsBuilder.UseInMemoryDatabase();

            MembershipContext context = new MembershipContext(optionsBuilder.Options);

            Member member1 = new Member()
            {
                MemberId = 1,
                FirstName = "James",
                LastName = "Jones"
            };

            context.Members.Add(member1);
            context.SaveChanges();
            return context;
        }

    }

    public class Member
    {
        public int MemberId { get; set; }
        public string FirstName { get; set; }
        public string LastName { get; set; }

        public override string ToString()
        {
            return $"{MemberId} {FirstName} {LastName}";
        }
    }

    public class MembershipContext : DbContext
    {
        public MembershipContext(DbContextOptions options)
        : base(options) {}
        public DbSet<Member> Members { get; set; }
    }
}

调用MembershipContext m2 = p.GetNewContext();后,context.SaveChanges()上会抛出异常。

  

类型&#39; System.ArgumentException&#39;的例外情况发生在EntityFramework.Core.dll中但未在用户代码中处理

     

附加信息:具有相同键但不同的元素   价值已经存在。键:   Microsoft.Data.Entity.ChangeTracking.Internal.SimpleKeyValue`1 [System.Int32]

我知道发生了什么,但我不知道为什么。

第二次调用MembershipContext context = new MembershipContext(optionsBuilder.Options);时,会创建上下文,但是context.Members从第一次创建上下文时就已经有了条目,因此是异常。

1 个答案:

答案 0 :(得分:1)

这不是一个错误,它是一个功能。 https://github.com/aspnet/EntityFramework.Docs/issues/95

以下是使用DI的建议方式。

using System;
using Microsoft.Data.Entity;
using Microsoft.Data.Entity.Infrastructure;
using Microsoft.Extensions.DependencyInjection;

namespace EF7InMemoryBug
{
    public class Program
    {
        public static void Main(string[] args)
        {
            Program p = new Program();
            MembershipContext m1 = p.GetNewContext();
            MembershipContext m2 = p.GetNewContext();

            foreach (var member in m1.Members)
            {
                Console.WriteLine(member);
            }

            foreach (var member in m2.Members)
            {
                Console.WriteLine(member);
            }
        }

        private MembershipContext GetNewContext()
        {
            var serviceCollection = new ServiceCollection();
            serviceCollection
                .AddEntityFramework()
                .AddInMemoryDatabase()
                .AddDbContext<MembershipContext>(c => c.UseInMemoryDatabase());

            MembershipContext context = serviceCollection.BuildServiceProvider().GetService<MembershipContext>();

            Member member1 = new Member()
            {
                MemberId = 1,
                FirstName = "James",
                LastName = "Jones"
            };

            context.Members.Add(member1);
            context.SaveChanges();
            return context;
        }

    }

    public class Member
    {
        public int MemberId { get; set; }
        public string FirstName { get; set; }
        public string LastName { get; set; }

        public override string ToString()
        {
            return $"{MemberId} {FirstName} {LastName}";
        }
    }

    public class MembershipContext : DbContext
    {
        public MembershipContext(DbContextOptions options)
        : base(options) {}
        public DbSet<Member> Members { get; set; }
    }
}