엔터티 프레임 워크 7 메모리 데이터베이스 예외

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(); 호출 한 후 MembershipContext m2 = p.GetNewContext(); context.SaveChanges() 에 대한 예외가 발생합니다.

EntityFramework.Core.dll에서 'System.ArgumentException'유형의 예외가 발생했지만 사용자 코드에서 처리되지 않았습니다.

추가 정보 : 동일한 키이지만 값이 다른 요소가 이미 있습니다. 키 : Microsoft.Data.Entity.ChangeTracking.Internal.SimpleKeyValue`1 [System.Int32]

무슨 일이 일어나는 지 알지만, 왜 그런지 모르겠습니다.

MembershipContext context = new MembershipContext(optionsBuilder.Options); 두 번째로 호출하면 컨텍스트가 생성되지만 context.Members 이미 컨텍스트를 처음 만들 때부터 항목을 가지므로 예외가 생성됩니다.

수락 된 답변

버그는 아니며 기능입니다. 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; }
    }
}



아래 라이선스: CC-BY-SA with attribution
와 제휴하지 않음 Stack Overflow
이 KB는 합법적입니까? 예, 이유를 알아보십시오.
아래 라이선스: CC-BY-SA with attribution
와 제휴하지 않음 Stack Overflow
이 KB는 합법적입니까? 예, 이유를 알아보십시오.