Partiye beş yıl geç kaldı.
Kabul edilen yanıtın sağlanan bağlantılarında belirtilmiştir, ancak bence SO - dinamik olarak sağlanan parametrelere dayalı olarak sorguyu oluşturma konusunda açık bir cevabı hak ediyor. Örneğin:
Kurmak
-- 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
prosedür
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
kullanım
exec spDoSearch @TopCount = 3
exec spDoSearch @FirstName = 'Dick'
Artıları:
- yazması ve anlaması kolay
- esneklik - daha zor filtreler için sorguyu kolayca oluşturun (ör. dinamik TOP)
Eksileri:
- sağlanan parametrelere, dizinlere ve veri hacmine bağlı olarak olası performans sorunları
Doğrudan cevap değil, sorunla ilgili büyük resim
Genellikle, bu filtreleme saklı yordamları yüzer, ancak bazı hizmet katmanlarından çağrılır. Bu, iş mantığını (filtreleme) SQL'den hizmet katmanına taşıma seçeneğini bırakır.
Bir örnek, sağlanan filtrelere dayalı olarak sorgu oluşturmak için LINQ2SQL kullanmaktır:
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;
}
Artıları:
- sağlanan filtrelere dayalı dinamik olarak oluşturulan sorgu. Hiçbir parametre koklama veya yeniden derleme ipuçları gerekli
- OOP dünyasındaki insanlar için yazmak biraz daha kolay
- "basit" sorgular yayınlanacağı için genellikle performans dostudur (yine de uygun dizinlere ihtiyaç vardır)
Eksileri:
- LINQ2QL sınırlamalarına ulaşılabilir ve duruma bağlı olarak LINQ2Objects sürümüne geçmeye veya saf SQL çözümüne geri dönmeye zorlanabilir
- LINQ'nun dikkatsizce yazılması korkunç sorgular (veya navigasyon özellikleri yüklüyse birçok sorgu) oluşturabilir