C\#표현 식 의 동적 조회 상세 설명[번역]
LINQ 를 사용 하여 데이터 베 이 스 를 처리 할 때 이런 체험 은 신기 한 체험 입 니 다.맞 습 니까?데이터베이스 실 체 를 일반적인 수집 처럼 Linq 에서 Where,Select 또는 Take 와 같이 간단하게 사용 하면 코드 를 사용 할 수 있 습 니 다.
그러나 동적 조회 와 표현 식 트 리 를 통 해 이 기능 을 어떻게 실현 하 는 지 생각해 보 자.막후 에서 일어 난 일.작성 한 LINQ 조 회 는 SQL(또는 다른 방식)로 변환 되 며,이 SQL 조 회 를 데이터베이스 에 보 냅 니 다.그리고 데이터베이스 응답 을 C#1 대상 에 표시 합 니 다.그런데 어떻게 SQL 로 완전히 전환 합 니까?
본 논문 에서 Entity Framework 나 MongoDB C#드라이버 와 같은 프레임 워 크 가 표현 식 트 리 를 어떻게 사용 하 는 지 볼 수 있 습 니 다.동적 조 회 를 만 들 기 위해 표현 식 트 리 를 직접 사용 하 는 방법 을 볼 수 있 습 니 다.이 조 회 는 컴 파일 할 때 만 들 수 없 는 조회 입 니 다.이 조 회 는 실행 중인 외관 만 알 수 있 기 때 문 입 니 다.
검색 가능 한 트 리 와 표현 식 트 리 를 비밀 로 합 니 다.
Entity Framework 6 의 C#코드 를 사용 하 는 것 을 고려 합 니 다.
DbSet<Student> students = context.Students;
var billie = await students.Where(s => s.StudentName == "Billie").ToListAsync();
실행 시 실제 프레임 워 크 는 다음 과 같은 SQL 조 회 를 생 성 합 니 다.
SQL:SELECT
[Extent1].[StudentID] AS [StudentID],
[Extent1].[StudentName] AS [StudentName],
[Extent1].[DateOfBirth] AS [DateOfBirth],
FROM [dbo].[Students] AS [Extent1]
WHERE N'Billie' = [Extent1].[StudentName]
WHERESQL 조회 에서 동작 이 있 습 니 다.그 건 뻔 하지 않 아 요.SQL 에 WHERE 가 포함 되 어 있 지 않 으 면 모든 학생 이 데이터베이스 에서 가 져 가 고 선별 은.NET 프로 세 스에 서 실 행 됩 니 다.실제로 다음 코드 는 이 점 을 할 수 있다.
//BAD:
DbSet<Student> students = context.Students;
Func<Student, bool> predicate = s => s.StudentName == "Billie";
var x = students.Where(predicate).ToList();
마지막 예제 에서 SQL 조 회 는 모든 학생 을 절차 에 들 어가 게 하고 이 를 일반적인 집합 에 투사 합 니 다.다른 점 은 첫 번 째 코드 에서 lambda 는 Expression두 번 째 코드 는 성능,메모리,네트워크 면 에서 매우 나쁘다.우 리 는 데이터베이스 에서 만 항목 을 얻 는 것 이 아니 라 네트워크 에서 많은 대상 을 얻 었 다.그리고 우 리 는 CPU 를 사용 하여 그것들 을 C#1 대상 으로 정렬 합 니 다.프로 세 스 더미 에 메모 리 를 저장 합 니 다.
그래서 첫 번 째 코드 로 돌아 가자.어떻게 await students.Where(s=>s.StudentName=="Billie").ToListAsync()에 포 함 된 SQL 조회 WHERE N'Billie'=[Extent 1]을 만 듭 니까?
정 답 은 표현 트 리.이 코드 s=>s.StudentName=="Billie"는 실제 구조 화 된 조회 로 프로 그래 밍 을 통 해 노드 트 리 로 분해 할 수 있 습 니 다.이 예제 에는 6 개의 노드 가 있다.맨 윗 층 의 노드 는 lambda 표현 식 입 니 다.왼쪽 은 lambda 인자 입 니 다.오른쪽 은 Equal 표현 식 을 나타 내 는 lambda 주체 입 니 다.실체 프레임 워 크 는 이 표현 식 트 리 를 옮 겨 다 니 며 SQL 조 회 를 구성 하 는 알고리즘 을 가지 고 있 습 니 다.다른 데이터 원본 공급 자(예 를 들 어 Mongo DB C#드라이버)도 같은 일이 발생 할 수 있 습 니 다.이 는 MongoDB json 조 회 를 구성 하 는 것 을 제외 하고.
C#표현 식 트 리
첫 번 째 코드 에서 유형 s=>s.StudentName=="Billie"는 Expression
좋 습 니 다.그런데 어떻게 이용 해 야 하나 요?
대부분의 경우 표현 나 무 를 사용 하 는 사람들 은 세계 실체 구 조 를 구축 하 는 사람들 이다.그러나 특정 상황 에 서 는 유용 해 졌 다.이것 은 우리 가 최근 에 Ozcode[1](나의 일상 업무)에서 만난 사례 이다.
Error 라 는 데이터베이스 실체 에 동적 서버 단 필 터 를 만 들 고 싶 습 니 다.이 실 체 는 많은 속성 을 가지 고 있 습 니 다.우 리 는 사용자 가 그것 을 여과 할 수 있 도록 허락 하 기 를 바 랍 니 다.따라서 필 터 는 허 용 된 Username,Country,Version 또는 기타 재산 에 따라 야 한다.이것 은 우리 가 실현 해 야 할 API 입 니 다.
IQueryable<Error> _errors;
public IEnumerable<Error> GetErrors(string propertyToFilter, string value){ /*..*/}
이 경우 property ToFilter 는 속성 Error 입 니 다.일반적인 LINQ 를 사용 하 는 유일한 방법 은 커 다란 switch/case 문 구 를 사용 하 는 것 입 니 다.약간 이렇게...
IQueryable<Error> _errors;
public IEnumerable<Error> GetErrors(string propertyToFilter, string value)
{
switch (propertyToFilter)
{
case "Username":
return await _errors.Where(e=> e.Username == value).ToListAsync();
case "Country":
return await _errors.Where(e=> e.Country == value).ToListAsync();
case "Version":
return await _errors.Where(e=> e.Version == value).ToListAsync();
// ...
}
}
이상 적 인 선택 이 아니 라 는 것 에 동의 하 실 수도 있 습 니 다.이 모든 것 을 작성 해 야 하 는 것 외 에 도 오류 가 발생 하기 쉽다.속성 을 추가 하면 어떻게 합 니까?이름 을 바 꾸 면 어떻게 합 니까?모든 일이 엉망진창이다.동적 조회 와 표현 식 트 리 를 통 해 이 기능 을 실현 할 수 있 는 방법 은 다음 과 같 습 니 다.
private async static Task<IEnumerable<Error>> GetErrors(string propertyToFilter, string value)
{
var error = Expression.Parameter(typeof(Error));
var memberAccess = Expression.PropertyOrField(error, propertyToFilter);
var exprRight = Expression.Constant(value);
var equalExpr = Expression.Equal(memberAccess, exprRight);
Expression<Func<Error, bool>> lambda = Expression.Lambda<Func<Error, bool>>(equalExpr, error);
return await _errors.Where(lambda).ToListAsync();
}
이 줄 의 코드 는 표현 식 트 리 의 노드 를 대표 합 니 다.그것들 은 공동으로 최고 노드-lambda 를 구성 했다.그리고 LINQ 에서 동적 표현 식 을 사용 하고 서버 쪽 SQL 조 회 를 생 성 할 수 있 습 니 다.나 는 매우 좋다 고 생각한다.이 문 제 를 해결 하 는 또 다른 방법 은 사용자 정의 SQL 조회 문자열 을 구축 하 는 것 입 니 다.Ozcode 에서 저 희 는 MongoDB 를 사용 하기 때문에 SQL 은 사용 하기에 적합 하지 않 지만 사용자 정의 MongoDB JSON 조회 문자열 을 만 들 수 있 습 니 다.어렵 지 는 않 지만 표현 식 트 리 방법 이 더 유연 하고 믿 을 만하 다 고 생각 합 니 다.한편,LINQ 에 넣 고 다른 LINQ 연산 자 와 조합 할 수 있 습 니 다.또한,Entity Framework 와 같은 테스트 를 거 친 프레임 워 크 가 이 작업 을 수행 할 수 있 을 때 왜 자신의 조 회 를 작성 해 야 합 니까?
개요
돌 이 켜 보면이것 은 본문 중의 몇 가지 관건 이다.
•일반적인 함수/의뢰 와 표현 식 간 의 차 이 는 표현 식 이 구조 화 트 리 로 표시 할 수 있다 는 것 입 니 다.데이터베이스 조회 와 같은 것 을 만 들 기 위해 서 트 리 를 쉽게 분석 할 수 있 습 니 다.
•표현 식 을 지원 하 는 데이터 원본 은 이 IQueryable 인 터 페 이 스 를 실현 합 니 다.
•표현 식(일반적인 방법 이나 의뢰 를 사용 할 수 없다 면,검색 은 데이터베이스 에 있 지 않 고 서버 에 있 을 것 입 니 다.이것 은 성능 에 있어 서 무 서운 것 입 니 다.
•lambda(주체 가 없 음)를 사용 할 때 표현 식 은 빈 틈 없 이 만 들 어 졌 기 때문에 몇 년 동안 계속 그 랬 을 수도 있 습 니 다.
•동적 조 회 를 만 들 기 위해 표현 식 트 리 를 사용 할 수 있 습 니 다.이것 은 컴 파일 할 수 없 을 때 실행 할 때 만 조 회 를 구축 하 는 데 유용 하 다.
총결산
C\#표현 식 의 동적 조회 에 관 한 이 글 은 여기까지 소개 되 었 습 니 다.더 많은 C\#표현 식 의 동적 조회 내용 은 우리 의 이전 글 을 검색 하거나 아래 의 관련 글 을 계속 찾 아 보 세 요.앞으로 많은 응원 바 랍 니 다!
References
[1] Ozcode: https://oz-code.com
[2]: https://www.mediavine.com/
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
C#Task를 사용하여 비동기식 작업을 수행하는 방법라인이 완성된 후에 이 라인을 다시 시작할 수 없습니다.반대로 조인(Join)만 결합할 수 있습니다 (프로세스가 현재 라인을 막습니다). 임무는 조합할 수 있는 것이다. 연장을 사용하여 그것들을 한데 연결시키는 것이...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.