สายไปงานเลี้ยงห้าปี
มันถูกกล่าวถึงในลิงก์ที่ให้ไว้ของคำตอบที่ยอมรับ แต่ฉันคิดว่ามันสมควรได้รับคำตอบที่ชัดเจนเกี่ยวกับ SO - การสร้างแบบสอบถามแบบไดนามิกตามพารามิเตอร์ที่ให้ไว้ เช่น:
ติดตั้ง
-- 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
ขั้นตอน
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
การใช้
exec spDoSearch @TopCount = 3
exec spDoSearch @FirstName = 'Dick'
ข้อดี:
- ง่ายต่อการเขียนและเข้าใจ
- ความยืดหยุ่น - สร้างข้อความค้นหาสำหรับการกรองที่ซับซ้อนได้ง่าย (เช่นไดนามิก TOP)
จุดด้อย:
- ปัญหาประสิทธิภาพที่เป็นไปได้ขึ้นอยู่กับพารามิเตอร์ดัชนีและปริมาณข้อมูลที่ให้
ไม่ใช่คำตอบโดยตรง แต่เกี่ยวข้องกับปัญหา aka ภาพรวมขนาดใหญ่
โดยปกติแล้วขั้นตอนการจัดเก็บตัวกรองเหล่านี้จะไม่ลอยไปมา แต่ถูกเรียกจากชั้นบริการบางแห่ง สิ่งนี้ทำให้ตัวเลือกในการย้ายตรรกะทางธุรกิจออกไป (กรอง) จาก SQL ไปยังชั้นบริการ
ตัวอย่างหนึ่งคือการใช้ LINQ2SQL เพื่อสร้างแบบสอบถามตามตัวกรองที่มีให้:
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;
}
ข้อดี:
- ข้อความค้นหาที่สร้างขึ้นแบบไดนามิกตามตัวกรองที่มีให้ ไม่จำเป็นต้องดมพารามิเตอร์หรือคอมไพล์คำแนะนำซ้ำ
- ค่อนข้างง่ายที่จะเขียนสำหรับผู้ที่อยู่ในโลกของ OOP
- โดยทั่วไปจะเป็นมิตรกับประสิทธิภาพเนื่องจากจะมีการออกข้อความค้นหา "แบบง่าย" (ดัชนีที่เหมาะสมยังคงต้องการ)
จุดด้อย:
- อาจถึงข้อ จำกัด ของ LINQ2QL และบังคับให้ลดระดับเป็น LINQ2Objects หรือกลับไปใช้โซลูชัน SQL บริสุทธิ์ขึ้นอยู่กับกรณีและปัญหา
- การเขียนอย่างไม่ระมัดระวังของ LINQ อาจสร้างข้อความค้นหาที่น่ากลัว (หรือแบบสอบถามจำนวนมากหากโหลดคุณสมบัติการนำทาง)