동적으로 DbContext에서 일반 DbSet 찾기

.net asp.net-mvc-5 c# entity-framework-core

문제

나는이 질문이 이미 요구되었음을 알고 있지만 나는 나를 만족시키는 답을 찾을 수 없었다. 내가 뭘 DbSet<T> 유형의 이름을 기반으로 특정 DbSet<T> 를 검색하는 것입니다.

나는 다음과 같은 것을 가지고있다.

[assembly: System.Runtime.CompilerServices.InternalsVisibleTo("MyDllAssemblyName")]
[assembly: System.Runtime.CompilerServices.InternalsVisibleTo("MyCallingAssemblyName")]

class MyDbContext : DbContext {

    public DbSet<ModelA> A { get; set; }
    public DbSet<ModelB> B { get; set; }

    public dynamic GetByName_SwitchTest(string name) {
        switch (name) {
            case "A": return A;
            case "B": return B;
        }
    }

    public dynamic GetByName_ReflectionTest(string fullname)
    {
        Type targetType = Type.GetType(fullname);
        var model = GetType()
            .GetRuntimeProperties()
            .Where(o => 
                o.PropertyType.IsGenericType &&
                o.PropertyType.GetGenericTypeDefinition() == typeof(DbSet<>) &&
                o.PropertyType.GenericTypeArguments.Contains(targetType))
            .FirstOrDefault();
        if (null != model)
            return model.GetValue(this);
        return null;
    }
}

간단한 전환이나 반사를 통해 유형 자체를 가져 오는 데 문제가 없습니다. 그러나 DbSet 타입이 무엇인지 알지 못하기 때문에 유형을 동적으로 반환해야합니다. 그런 다음 동일한 어셈블리의 다른 어딘가에서이 방법으로 사용합니다.

// MyDbContext MyDbContextInstance..
var model = MyDbContextInstance.GetByName_SwitchTest("A");
var record1 = model.FirstOrDefault(); // It crashes here with RunTimeBinderException

이 시점에서 modelInternalDbSet<ModelA> 유형의 인스턴스를 포함합니다. 거기에서, 내가 RunTimeBinderException 얻을 model 개체와 함께 할 : 'Microsoft.Data.Entity.Internal.InternalDbSet'에 대한 정의가 포함되어 있지 않습니다 'FirstOrDefault'

웹에서 조사한 결과, 블로그 게시물에 다음과 같은 내용이 설명되어 있습니다.

FirstOrDefault ()에 대한 호출이 실패하는 이유는 런타임에 모델의 유형 정보를 사용할 수 없기 때문입니다. 익명 형식이 공개되지 않기 때문에 사용할 수없는 이유가 있습니다. 메서드가 익명 형식의 인스턴스를 반환하면 익명 형식의 인스턴스를 참조하는 System.Object를 반환합니다.이 형식의 정보는 주 프로그램에서 사용할 수 없습니다.

그리고 그는 그 해결책을 지적합니다 :

해결책은 실제로 매우 간단합니다. 우리가해야 할 일은 ClassLibrary1 프로젝트의 AssemplyInfo.cs를 열고 다음 줄을 추가하는 것입니다 : [assembly:InternalsVisibleTo("assembly-name")]

내 코드에서이 솔루션을 시도했지만 작동하지 않습니다. 정보를 위해 나는 dnx dotnet46에서 실행되는 두 개의 어셈블리로 구성된 asp.net 5 솔루션을 가지고 있습니다. 내 모든 모델과 DbContext를 포함하는 응용 프로그램과 dll 모든 관련 전화는 내가 dll에 위치하고 있습니다.

이 솔루션이 작동 할 기회가 있습니까? 내가 놓친 게 있니? 모든 포인터가 크게 감사하겠습니다?

미리 감사드립니다.

[편집하다]

내가 돌아 시도 IQueryable<dynamic> 보다는 dynamic 나는 기본적인 쿼리 할 수 model.FirstOrDefault(); 하지만 무엇보다 필드에서 필터링 할 수 있기를 원합니다.

var record = model.FirstOrDefault(item => item.MyProperty == true);

인기 답변

컴파일하는 동안 <T> 모르는 경우 어떻게했을까요?

먼저 DbContext.Set 메서드가 컨텍스트 및 기본 저장소에서 지정된 형식의 엔터티에 액세스하기 위해 비 제네시 DbSet 인스턴스를 반환하도록 형식을 가져와야 합니다.

public virtual DbSet Set(Type entityType)

여기서 인수는 집합이 반환되어야하는 엔터티의 형식입니다. 주어진 엔터티 형식에 대해 설정된 값은 반환 값입니다.

var type = Assembly.GetExecutingAssembly().GetTypes().FirstOrDefault(t => t.Name == <Pass your table name>);

이제는이 유형을 갖게되었습니다.

if(type != null)
{
DbSet context = context.Set(type);
}

또는 하나의 라이너가 될 것입니다.

DbSet mySet = context.Set(Type.GetType("<Your Entity Name>"));



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