Lima tahun terlambat ke pesta.
Disebutkan dalam tautan yang disediakan dari jawaban yang diterima, tetapi saya pikir itu layak mendapatkan jawaban eksplisit pada SO - secara dinamis membangun kueri berdasarkan parameter yang disediakan. Misalnya:
Mempersiapkan
-- drop table Person
create table Person
(
PersonId INT NOT NULL IDENTITY(1, 1) CONSTRAINT PK_Person PRIMARY KEY,
FirstName NVARCHAR(64) NOT NULL,
LastName NVARCHAR(64) NOT NULL,
Title NVARCHAR(64) NULL
)
GO
INSERT INTO Person (FirstName, LastName, Title)
VALUES ('Dick', 'Ormsby', 'Mr'), ('Serena', 'Kroeger', 'Ms'),
('Marina', 'Losoya', 'Mrs'), ('Shakita', 'Grate', 'Ms'),
('Bethann', 'Zellner', 'Ms'), ('Dexter', 'Shaw', 'Mr'),
('Zona', 'Halligan', 'Ms'), ('Fiona', 'Cassity', 'Ms'),
('Sherron', 'Janowski', 'Ms'), ('Melinda', 'Cormier', 'Ms')
GO
Prosedur
ALTER PROCEDURE spDoSearch
@FirstName varchar(64) = null,
@LastName varchar(64) = null,
@Title varchar(64) = null,
@TopCount INT = 100
AS
BEGIN
DECLARE @SQL NVARCHAR(4000) = '
SELECT TOP ' + CAST(@TopCount AS VARCHAR) + ' *
FROM Person
WHERE 1 = 1'
PRINT @SQL
IF (@FirstName IS NOT NULL) SET @SQL = @SQL + ' AND FirstName = @FirstName'
IF (@LastName IS NOT NULL) SET @SQL = @SQL + ' AND FirstName = @LastName'
IF (@Title IS NOT NULL) SET @SQL = @SQL + ' AND Title = @Title'
EXEC sp_executesql @SQL, N'@TopCount INT, @FirstName varchar(25), @LastName varchar(25), @Title varchar(64)',
@TopCount, @FirstName, @LastName, @Title
END
GO
Pemakaian
exec spDoSearch @TopCount = 3
exec spDoSearch @FirstName = 'Dick'
Pro:
- mudah ditulis dan dimengerti
- fleksibilitas - mudah menghasilkan permintaan untuk penyaringan yang lebih rumit (mis. TOP dinamis)
Cons:
- kemungkinan masalah kinerja tergantung pada parameter yang disediakan, indeks dan volume data
Bukan jawaban langsung, tetapi terkait dengan masalah alias gambaran besarnya
Biasanya, prosedur tersimpan penyaringan ini tidak mengambang, tetapi dipanggil dari beberapa lapisan layanan. Ini meninggalkan pilihan untuk memindahkan logika bisnis (penyaringan) dari SQL ke lapisan layanan.
Salah satu contoh adalah menggunakan LINQ2SQL untuk menghasilkan kueri berdasarkan filter yang disediakan:
public IList<SomeServiceModel> GetServiceModels(CustomFilter filters)
{
var query = DataAccess.SomeRepository.AllNoTracking;
// partial and insensitive search
if (!string.IsNullOrWhiteSpace(filters.SomeName))
query = query.Where(item => item.SomeName.IndexOf(filters.SomeName, StringComparison.OrdinalIgnoreCase) != -1);
// filter by multiple selection
if ((filters.CreatedByList?.Count ?? 0) > 0)
query = query.Where(item => filters.CreatedByList.Contains(item.CreatedById));
if (filters.EnabledOnly)
query = query.Where(item => item.IsEnabled);
var modelList = query.ToList();
var serviceModelList = MappingService.MapEx<SomeDataModel, SomeServiceModel>(modelList);
return serviceModelList;
}
Pro:
- kueri yang dihasilkan secara dinamis berdasarkan filter yang disediakan. Tidak ada parameter mengendus atau mengkompilasi ulang petunjuk
- agak mudah untuk menulis untuk orang-orang di dunia OOP
- biasanya ramah kinerja, karena permintaan "sederhana" akan dikeluarkan (indeks yang sesuai masih diperlukan)
Cons:
- Keterbatasan LINQ2QL dapat dicapai dan memaksa downgrade ke LINQ2Objects atau kembali ke solusi SQL murni tergantung pada kasusnya
- penulisan LINQ yang ceroboh dapat menghasilkan pertanyaan yang mengerikan (atau banyak pertanyaan, jika properti navigasi dimuat)