LINQ에서 SQL DTOS 및 복합 객체
-
03-07-2019 - |
문제
LINQ 데이터 제공 업체에 LINQ 객체를 유지하고 필터링 등을 허용하기 위해 IQueryable을 반환하는 데 다른 사람들과 비슷한 접근 방식을 사용하고 있습니다. 이것은 ID 또는 기타 속성으로 간단한 개체를 필터링하는 데 적합하지만 문제가 있습니다. 다른 자식 객체로 구성된 테이블 개체에 가입
//CoreDBDataContext db = coreDB;
public IQueryable<DTO.Position> GetPositions() {
return from p in coreDB.Positions
select new DTO.Position
{
DTO.User = new DTO.User(p.User.id,p.User.username, p.User.firstName,p.User.lastName,p.User.email,p.User.isActive),
DTO.Role = new DTO.Role(p.Role.id, p.Role.name, p.Role.isActive),
DTO.OrgUnit = new DTO.OrgUnit(p.OrgUnit.id,p.OrgUnit.name,p.OrgUnit.isActive)
};
Coredb.Positions는 LINQ 위치 객체이며 사용자, OrgUnit 및 역할로 구성된 DTO 위치를 반환하고 있습니다 (기본 테이블은 userID, reaconID 및 orgUnitID와의 조인 테이블입니다).
내가 가진 문제는 iqueryable에 필터를 추가하려고 할 때 dto.user 객체에 사용할 수있는 번역이 없다는 SQL 오류가 발생한다는 것입니다.
public static IQueryable<Position> WithUserID(this IQueryable<Position> query, int userID)
{
return query.Where(p => p.User.ID == userID);
}
모든 Google 결과가 생성 된 LINQ 객체와 직접 작업하는 사람들과 함께있는 것처럼 보이 므로이 문제 해결 방법에 대해 완전히 손실됩니다.
이 일을하는 방법에 대한 생각이 있습니까, 아니면 여기서 완전히 잘못된 일을하고 있습니까?
감사
해결책 3
복잡한 쿼리에 필터를 사용하지 않았습니다. 대신,보다 복잡한 쿼리 요구 사항을 위해 저장소에 메소드를 추가했습니다. 이것이 시스템을 쉽게 이해하고 유지할 수있게 해줄 것이라고 생각합니다.
다른 팁
비슷한 접근 방식으로 성공적으로 일할 수있었습니다.
var courses = from c in Map(origCourses)
where !expiredStatuses.Contains(c.Status)
select c;
지도가있는 곳 :
select new UserCourseListItem
{
CourseID = c.CourseID,
CourseName = cm.CourseName,
CourseType = c.CourseType.Value
...
생성자 대신 해당 유형의 초기화로 시도하는 것은 어떻습니까?
추신. 이것은 작업 응용 프로그램의 일부이며, 만료 된 기타는 복잡한 표현과 관련이 있습니다.
Update 1: 이것은 언급 된 시나리오와 비교하여 유사합니다.
- 지도는 poco 객체 인 iqueryable을 반환합니다.
- poco 객체로 iqueryable을 반환하는 맵 메소드를 호출 한 후 필터를 적용하고 있습니다.
LINQ2SQL은 디자이너 생성 객체 만 이해합니다. 글쎄, 그것은 완전히 사실이 아니라 충분히 가깝습니다.
따라서 LINQ 쿼리를 다시 작성하면 LINQ2SQL 객체를 다시 작성하면 쿼리가 작성된 경우가 아니라 쿼리가 실제로 실행될 때 쿼리가 유효한 SQL로 변환됩니다. DTO 객체는 LINQ2SQL 객체가 아니기 때문에 LINQ2SQL은 적절한 SQL을 만드는 방법을 모릅니다.
이 방법으로 분리를 유지하려면 관련된 LINQ2SQL 객체 만 사용하여 쿼리를 실행하는 방법을 찾아 결과를 DTO에만 매핑해야합니다.
어쩌면 쿼리 메소드를 다시 작성할 수 있습니다.
업데이트: 매개 변수는 유형이어야합니다
Expression<>
, 그리고 반환 할 필요가 없습니다IQueryable<>
. 지적 해 주신 Freddy에게 감사합니다.
public IEnumerable<DTO.Position> FindPositions(Expression<Func<Position, bool>> criteria)
{
return from p in coreDB.Positions
where criteria.Invoke(p)
select new DTO.Position
{
User = new DTO.User(p.User.id, p.User.username, p.User.firstName, p.User.lastName,
p.User.email, p.User.isActive),
Role = new DTO.Role(p.Role.id, p.Role.name, p.Role.isActive),
OrgUnit = new DTO.OrgUnit(p.OrgUnit.id, p.OrgUnit.name, p.OrgUnit.isActive)
};
}