Vâng, "tham gia" là khó khăn, bởi vì nó là rất khó để thể hiện một tham gia - nhưng những thứ như nơi/select/orderby là khá dễ dàng ...
Thực sự, nó chỉ là trường hợp kết hợp các phương pháp LINQ khác nhau trên IQueryable<T>
, thường chấp nhận Expression<Func<...>>
cho một số kết hợp. Vì vậy, một cơ bản chọn với một vị ngữ tùy chọn sẽ là:
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;
}
tôi sẽ có xu hướng quay trở lại IQueryable<T>
quá, vì đó là hoàn toàn composable. Nếu người gọi muốn một danh sách, họ luôn có thể sử dụng ToList()
vào nó ... hoặc (ví dụ):
using(var ctx = new MyDataContext(CONN))
{
ctx.Log = Console.Out;
int frCount = ctx.Get<Customer>(c => c.Country == "France").Count();
}
đó (sử dụng Northwind) thực hiện truy vấn:
SELECT COUNT(*) AS [value]
FROM [dbo].[Customers] AS [t0]
WHERE [t0].[Country] = @p0
Vấn đề với bao gồm "select" (chiếu) trong truy vấn là bạn sẽ kết thúc với nhiều loại generic. Vì bạn thường muốn phép chiếu là một loại ẩn danh, nên sẽ không thể xác định loại chiếu (ẩn danh) và loại bảng và nó sẽ không thể gọi được.
Trong thực tế, tôi tự hỏi liệu có nhiều lợi ích khi viết một phương pháp như vậy không.Tôi chỉ có thể gắn bó với một phương pháp cơ bản:
public IQueryable<T> Get<T>() where T : class
{
return (IQueryable<T>)GetTable(typeof(T));
}
Và để cho người gọi soạn nó theo cách ưa thích của họ - có lẽ với cú pháp truy vấn:
var list = (from cust in ctx.Get<Customer>()
where cust.Country == "France"
select cust.CompanyName).Take(10).ToList();
nào sử dụng:
SELECT TOP (10) [t0].[CompanyName]
FROM [dbo].[Customers] AS [t0]
WHERE [t0].[Country] = @p0
Ngoài ra, nếu bạn thực sự muốn bao gồm thứ tự và chiếu, thì phương pháp mở rộng là phương thức thực tế nhất h; sau đó bạn không cần phải xác định (nguồn) ban đầu T (đó là những gì làm cho nó uncallable khi trộn với anon-loại):
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);
}
}
Sau đó, hãy xem xét một phương pháp Dal như:
public List<string> Countries()
{
return Customers.Get(
x=>x.CompanyName != "",
x=>x.Country,
x=>x).Distinct().ToList();
}
Trong đó sử dụng (một lần nữa, với Northwind):
SELECT DISTINCT [t0].[Country]
FROM [dbo].[Customers] AS [t0]
WHERE [t0].[CompanyName] <> @p0
Tôi thực sự lo lắng về điều đó. Thực tế là nó biên dịch các vị từ có nghĩa là nó sẽ luôn luôn tải toàn bộ bảng, sau đó làm LINQ-to-Objects trên nó. Đó là ** rất ** không hiệu quả. –
Đồng ý, sẽ có hiệu suất kém ... – CMS