linq 쿼리의 일부를 함수로 전달할 수 있습니까? 항상 같은 쿼리 인터페이스를 사용하는 DAL 용 공용 인터페이스를 만들고 싶습니다. 예를 들어,
List<T> Get(Join j, Where w, Select s){
return currentDataContext<T>.Join(j).Where(w).Select(s).ToList();
}
이런 일이 가능합니까? 표현식 트리를 사용하여 완성 될 것이라고 생각하지만 예제를 찾을 수 없었습니다.
join을 표현하는 것이 매우 어렵 기 때문에 "join"은 까다 롭습니다. 그러나 / select / orderby와 같은 것은 매우 쉽습니다 ...
실제로, IQueryable<T>
에 다양한 LINQ 메서드를 결합한 경우가 있습니다.이 메서드는 일반적으로 Expression<Func<...>>
을 일부 조합으로 받아들입니다. 따라서 선택적 술어를 사용하는 기본 선택은 다음과 같습니다.
public IQueryable<T> Get<T>(
Expression<Func<T,bool>> predicate
) where T : class
{
IQueryable<T> query = (IQueryable<T>)GetTable(typeof(T));
if (predicate != null) query = query.Where(predicate);
return query;
}
IQueryable<T>
도 완벽하게 구성 할 수 있으므로 반환하는 경향이 있습니다. 호출자가 목록을 원하면 ToList()
또는 ... (예 ToList()
사용할 수 있습니다.
using(var ctx = new MyDataContext(CONN))
{
ctx.Log = Console.Out;
int frCount = ctx.Get<Customer>(c => c.Country == "France").Count();
}
(Northwind를 사용하여) 쿼리를 수행합니다.
SELECT COUNT(*) AS [value]
FROM [dbo].[Customers] AS [t0]
WHERE [t0].[Country] = @p0
쿼리에서 "선택"(투영)을 포함 할 때의 문제점은 여러 일반 유형으로 끝나야한다는 것입니다. 투영을 익명 형식으로하고 싶기 때문에 투영 형식 (익명) 과 테이블 형식을 지정하는 것은 거의 불가능하며 호출 할 수 없습니다.
실제로 그러한 방법을 쓰는 데 많은 이점이 있는지 궁금합니다. 나는 기본 방법을 고수 할 수 있습니다.
public IQueryable<T> Get<T>() where T : class
{
return (IQueryable<T>)GetTable(typeof(T));
}
그리고 호출자가 선호하는 방법으로 - 아마도 쿼리 구문을 사용하여 작성하게하십시오.
var list = (from cust in ctx.Get<Customer>()
where cust.Country == "France"
select cust.CompanyName).Take(10).ToList();
어떤 것을 사용 :
SELECT TOP (10) [t0].[CompanyName]
FROM [dbo].[Customers] AS [t0]
WHERE [t0].[Country] = @p0
또는 주문서와 프로젝션을 실제로 포함하려면 확장 방법이 가장 실용적인 방법입니다. 원본 (소스) T를 지정하지 않아도됩니다 (anon-types과 섞인 경우 uncallable이됩니다).
public static class QueryExtension
{
public static IQueryable<TProjection>
Get<TSource, TProjection, TOrderKey>(
this IQueryable<TSource> source,
Expression<Func<TSource, bool>> where, // optional
Expression<Func<TSource, TProjection>> select,
Expression<Func<TProjection, TOrderKey>> orderBy)
{
if (where != null) source = source.Where(where);
return source.Select(select).OrderBy(orderBy);
}
}
그런 다음 DAL 방법을 고려하십시오.
public List<string> Countries()
{
return Customers.Get(
x=>x.CompanyName != "",
x=>x.Country,
x=>x).Distinct().ToList();
}
어떤 것을 사용 하는가 (다시, Northwind와 함께) :
SELECT DISTINCT [t0].[Country]
FROM [dbo].[Customers] AS [t0]
WHERE [t0].[CompanyName] <> @p0
이 일반 클래스를 확인하십시오 : TableView.cs .
기본적으로 Func <TEntity, bool> 대리자를 사용하여 Where 조건자를 적용합니다.
//...
public TableView(DataContext dataContext, Expression<Func<TEntity, bool>> predicate)
{
this.table = dataContext.GetTable<TEntity>();
this.baseQuery = table.Where(predicate);
this.predicate = predicate.Compile();
}
//...