다음은 리플렉션을 사용하지 않고 다른 컨텍스트에서 런타임에 다른 테이블을 업데이트 할 수있는 작업 코드입니다.
namespace DemoContexts
{
using System;
using System.Collections.Generic;
using System.Data.Entity;
using System.Linq;
public interface IThing
{
int Id { get; set; }
int Status { get; set; }
}
public class FirstPersonThing : IThing
{
[System.ComponentModel.DataAnnotations.Key]
public int Id { get; set; }
public int Status { get; set; }
public string Foo { get; set; }
}
public class SecondPersonThing : IThing
{
[System.ComponentModel.DataAnnotations.Key]
public int Id { get; set; }
public int Status { get; set; }
public string Bar { get; set; }
}
public class FirstContext : DbContext
{
public FirstContext() : base("FirstContext") { }
public DbSet<FirstPersonThing> MyThings { get; set; }
public DbSet<SecondPersonThing> YourThings { get; set; }
}
public class SecondContext : DbContext
{
public SecondContext() : base("SecondContext") { }
public DbSet<FirstPersonThing> MyThings { get; set; }
public DbSet<SecondPersonThing> YourThings { get; set; }
}
class Program
{
static void Main(string[] args)
{
int contextType = 1;
int thingType = 1;
DbContext db = RunTimeCreatedContext(contextType);
IQueryable<IThing> collection = RunTimeCreatedCollection(db, thingType);
UpdateRuntimeDeterminedThings(db, collection, 1);
Console.ReadLine();
}
public static void UpdateRuntimeDeterminedThings(DbContext db,
IQueryable<IThing> collection,
int formId)
{
var querySet = collection.Where(p => p.Id == formId).ToList();
foreach (var result in querySet)
{
result.Status = 0;
}
db.SaveChanges();
}
static DbContext RunTimeCreatedContext(int contextType)
{
if (contextType == 0)
{
return new FirstContext();
}
else
{
return new SecondContext();
}
}
static IQueryable<IThing> RunTimeCreatedCollection(DbContext db, int thingType)
{
if (thingType == 0)
{
return db.Set(typeof(FirstPersonThing)) as IQueryable<IThing>;
}
else
{
return db.Set<SecondPersonThing>();
}
}
}
}
주의해야 할 첫 번째 일은이 모든 정적으로 이러한 개체는 공유 재산 서명이 있어야합니다 서로 다른 유형의 개체에 대한 일반적인 쿼리를 수행 할 수 있도록 입력되며,이 개념적으로 IThing 인터페이스로 표현된다는 점이다.
두 번째로 주목해야 할 점은 IQueryable이 어떻게 생성되는지입니다. 첫 번째 인스턴스 (FirstPersonThings의 경우)에서 DbContext.Set Method (Type)
에 의해 생성되고 두 번째 인스턴스의 DbContext.Set<TEntity> Method
에 의해 생성됩니다. 첫 번째는 런타임에 결정된 유형을 사용하고 캐스트가 필요하지만 런타임시 전달 유형을 사용하는 것이 유용 할 수 있으며 두 번째 유형은 generics를 사용하며 유형은 컴파일 타임에 결정됩니다. 분명히이 기능이 작동 할 수있는 여러 가지 다른 방법이 있습니다.
마지막으로 UpdateRuntimeDeterminedThings 메서드는 형식간에 공유되며 (기본 형식/상속 또는 인터페이스 구현과 함께) 속성과 메서드를 사용하기 때문에 작동합니다.
이것은 동적 프로그래밍 (동적 유형을 사용하여 가능함)이 아니며이 기능의 작동 방식을 설명하기 위해 동적이 아닌 런타임이라는 용어를 사용했습니다.
반사 ....? – gdoron
그로스 (Gross) ... 나는 그렇게하기를 원하지 않는다. SQL로 매우 쉽기 때문에 이렇게하는 방법이 있어야한다고 생각했다. – Tevis
모든 EF 엔티티에는'Id'와'Status' 속성이 있습니까? 문제는 LINQ 자체와 관련이 적습니다. C#은 정적으로 형식이 지정된 언어입니다. 일반에서 사용하려는 공통 속성을 나타내는 기본 형식을 사용하지 않고 (쉽게) 수행 할 수 없습니다. 질문. – rsenna