엔티티 프레임 워크는 데이터 쿼리에 대한 쿼리 조건이 종종 고정되어 있지 사용하는 경우, 우리는 동적 쿼리가 필요합니다. 구현하는 동적 쿼리는 동적 통해 람다 식을 구축 할 수 있습니다.
람다 표현식
람다 쉽게 표현 조건부 필터링 데이터를 사용할 수있다. 엔티티 프레임 워크는 해당 SQL 문에 람다 표현식이 실행된다.
예를 들어, 다음 코드 1 개 이름이 아닌 노인의 출력 :
네임 스페이스 ConsoleApp { 공용 클래스 사람 { 공공 문자열 이름은 { 얻을 ; 설정 ; } 공공의 INT의 나이 { 얻을 ; 설정 ; } } 클래스 MyDbContext : DbContext { 공공 DbSet <사람> 사람들은 { 얻을 ; 설정 ; } 보호 재정의 무효 OnConfiguring (DbContextOptionsBuilder optionsBuilder) { optionsBuilder.UseSqlServer ( "서버 = (로컬), 데이터베이스 =를 TestDB; 사용자 ID = sa를; 비밀 번호 = sa를; " ); } } 클래스 프로그램 { 정적 무효 메인 ( 문자열 []에 args) { MyDbContext dbContext = 새로운 MyDbContext () 의 foreach ( VAR의 항목 에 dbContext.People.Where (m => m.Age> 1 )) { 콘솔. 를 WriteLine (item.Name); } } } }
peoples.Where(m => m.Age > 1)
당신이 조건을 변경하고자하는 경우는, 내부 코드에 하드 코딩 된 코드를 변경해야합니다.
표현
발현 파라미터 m으로 분할되는 경우, 메인 인 내부 무엇에 표정이 속성의 값은 좌측 및 우측 파라미터 m 여기서, 작업자에 의해 수행되는 비교 동작이 중간보다 더 크다. 그래서 우리는 표현을 구축 할뿐만 아니라, 네 부분을 구축 할 필요가있을 때 :
- 매개 변수
- 매개 변수 속성
- 값
- 운영자
매개 변수
이름과 유형을 매개 변수 :
입력 유형 = 대해서 typeof (사람); VAR의 파라미터 = Expression.Parameter (유형, " m " );
재산
우리는 이름과 속성의 유형을 알 필요가, 반사 형 및 해당 매개 변수와 바로 연결하여 얻을 수 있습니다 :
PropertyInfo 속성 = type.GetProperty ( " 나이 " ); 식 expProperty = Expression.Property (파라미터 property.Name);
값
우리는 값 식을 구축해야합니다 :
식 <Func을 < 오브젝트 >> valueLamda = () => 1 ; 식 expValue = Expression.Convert (valueLamda.Body, property.PropertyType);
대리인의 반환 형식의 값이 대상이기 때문에 때문에 Expression.Convert가 올바른 형식으로 변환 사용하는 것이 필요하다.
값이 int와, 문자열 등의 간단한 형태 인 경우, 직접 사용할 수 있습니다 Expression.Constant
, 간단 :
식 expValue = Expression.Constant ( 1 );
운영자
이제 값 속성 식을 가지고, 다음 단계는 그들을 연결하는 연산자 식을 사용하는 것입니다 :
식 식 = Expression.GreaterThan (expProperty, expValue);
사용할 수있는 표현의 해당 유형으로 변환 :
식 <Func을 <이용시, BOOL >> 필터 = ((식 <Func을 <이용시, BOOL >> ) Expression.Lambda (식 변수)); foreach는 ( VAR의 항목 에 dbContext.People.Where (필터)) { Console.WriteLine (item.Name); }
여기에 전체 코드입니다
네임 스페이스 ConsoleApp { 공용 클래스 사람 { 공공 문자열 이름은 { 얻을 ; 설정 ; } 공공의 INT의 나이 { 얻을 ; 설정 ; } } 클래스 MyDbContext : DbContext { 공공 DbSet <사람> 사람들은 { 얻을 ; 설정 ; } 보호 재정의 무효 OnConfiguring (DbContextOptionsBuilder optionsBuilder) { optionsBuilder.UseSqlServer ( "서버 = (로컬), 데이터베이스 =를 TestDB; 사용자 ID = sa를; 비밀 번호 = sa를; " ); } } 클래스 프로그램 { 정적 무효 메인 ( 문자열 []에 args) { MyDbContext dbContext = 새로운 MyDbContext () 형 타입 = 대해서 typeof (사람), VAR의 파라미터 = Expression.Parameter (유형, " m " ) PropertyInfo 속성 = type.GetProperty ( " 나이 " ); 식 expProperty =Expression.Property (파라미터 property.Name); 식 <Func을 < 오브젝트 >> valueLamda = () => 1 ; 식 expValue = Expression.Convert (valueLamda.Body, property.PropertyType); 식 식 = Expression.GreaterThan (expProperty, expValue); 식 <Func을 <이용시, BOOL >> 필터 = ((식 <Func을 <이용시, BOOL >> ) Expression.Lambda (식 변수)); foreach는 ( var에 항목 에 dbContext.People.Where (필터)) { Console.WriteLine (item.Name); } } } }
이 동적 속성 이름과 값을 통과 동적 쿼리 수 있습니다.
포장 및 사용
우리는 몇 가지 간단한 패키지는,보다 편리 코드를 사용 않았다
https://github.com/SeriaWei/ZKEACMS/blob/master/src/EasyFrameWork/LINQ/Query.cs
조건을 추가하고, 마지막 식으로 설정하는 QueryCollection를 사용하여
정적 무효 메인 ( 문자열 []에 args) { MyDbContext dbContext = 새로운 MyDbContext (); QueryCollection 쿼리 = 새 QueryCollection (); queries.Add ( 새 쿼리 {이름 = " 나이 " , 연산자 = Query.Operators.GreaterThan, 값 = 1 }); foreach는 ( VAR의 항목 에 dbContext.People.Where (queries.AsExpression <이용시> ())) { Console.WriteLine (item.Name); } }
원본 주소 : http://www.zkea.net/codesnippet/detail/entity-framework-dynamic-search.html