รหัสนี้เป็นแบบตรงตามตัวพิมพ์เล็กและใหญ่
public IQueryable<FACILITY_ITEM> GetFacilityItemRootByDescription(string description)
{
return this.ObjectContext.FACILITY_ITEM.Where(fi => fi.DESCRIPTION.Contains(description));
}
รหัสนี้เป็นแบบตรงตามตัวพิมพ์เล็กและใหญ่
public IQueryable<FACILITY_ITEM> GetFacilityItemRootByDescription(string description)
{
return this.ObjectContext.FACILITY_ITEM.Where(fi => fi.DESCRIPTION.Contains(description));
}
คำตอบ:
สมมติว่าเรากำลังทำงานกับสตริงที่นี่นี่เป็นอีกวิธีที่ "สง่างาม" IndexOf()
โดยใช้
public IQueryable<FACILITY_ITEM> GetFacilityItemRootByDescription(string description)
{
return this.ObjectContext.FACILITY_ITEM
.Where(fi => fi.DESCRIPTION
.IndexOf(description, StringComparison.OrdinalIgnoreCase) != -1);
}
fi => fi.DESCRIPTION.ToLower().Contains(description.ToLower())
IEqualityComparer<string>
คุณลักษณะเพื่อจัดการกับการเปรียบเทียบจะทำงานอย่างไร ใช้ ToLower และ ToUpper เพื่อตรวจสอบความเท่าเทียมกันเป็นความคิดที่ไม่ดี ลอง: .Contains(description, StringComparer.CurrentCultureIgnoreCase)
ตัวอย่างเช่น
Error 1 'string' does not contain a definition for 'Contains' and the best extension method overload 'System.Linq.ParallelEnumerable.Contains<TSource>(System.Linq.ParallelQuery<TSource>, TSource, System.Collections.Generic.IEqualityComparer<TSource>)' has some invalid arguments
Contains
ด้วยStringComparer
ไม่ได้รับสตริงเป็นพารามิเตอร์ดังนั้นมันจะเป็น build-error IndexOf
บนQueryable
อาจไม่สามารถแปลเป็น SQL โดยส่วนตัวแล้วฉันพบว่าคำตอบนี้ใช้ได้อย่างสมบูรณ์ในขณะที่เราพูดถึง LINQ กับฐานข้อมูล
หากการสืบค้น LINQ ถูกดำเนินการในบริบทฐานข้อมูลการเรียกไปที่จะContains()
ถูกแมปไปยังLIKE
ผู้ประกอบการ:
.Where(a => a.Field.Contains("hello"))
Field LIKE '%hello%'
จะกลายเป็น
LIKE
ผู้ประกอบการเป็นกรณีตายตามค่าเริ่มต้น แต่ที่สามารถเปลี่ยนแปลงได้โดยเปลี่ยนการเปรียบเทียบของคอลัมน์
หากดำเนินการสืบค้น LINQ ในบริบท. NET คุณสามารถใช้IndexOf ()ได้ แต่วิธีดังกล่าวไม่ได้รับการสนับสนุนใน LINQ ไปยัง SQL
LINQ to SQL ไม่สนับสนุนวิธีการที่ใช้ CultureInfo เป็นพารามิเตอร์อาจเป็นเพราะไม่สามารถรับประกันได้ว่าเซิร์ฟเวอร์ SQL จะจัดการกับวัฒนธรรมแบบเดียวกันกับ. NET นี้ไม่เป็นความจริงอย่างสิ้นเชิงเพราะมันไม่StartsWith(string, StringComparison)
สนับสนุน
อย่างไรก็ตามดูเหมือนจะไม่สนับสนุนวิธีการประเมินLIKE
ใน LINQ กับ SQL และการเปรียบเทียบแบบ insensitive ของ case ใน. NET ทำให้เป็นไปไม่ได้ที่จะทำ case insensitive ประกอบด้วย () ในวิธีที่สอดคล้องกัน
insensitive
ค้นหาและอื่น ๆ case sensitive
ที่ผมต้องการให้เป็น ฉันต้องใช้ประสิทธิภาพในการเคาะและใช้ 'toLower ()' หรือไม่
คำตอบที่ยอมรับที่นี่ไม่ได้กล่าวถึงความจริงที่ว่าถ้าคุณมีสตริงที่ว่าง ToLower () จะโยนข้อยกเว้น วิธีที่ปลอดภัยกว่าคือ:
fi => (fi.DESCRIPTION ?? string.Empty).ToLower().Contains((description ?? string.Empty).ToLower())
การใช้ C # 6.0 (ซึ่งอนุญาตให้ใช้ฟังก์ชั่นการแสดงออกของร่างกายและการเผยแพร่ null) สำหรับ LINQ ไปยังวัตถุสามารถทำได้ในบรรทัดเดียวเช่นนี้ (ตรวจสอบ null)
public static bool ContainsInsensitive(this string str, string value) => str?.IndexOf(value, StringComparison.OrdinalIgnoreCase) >= 0;
IndexOf ทำงานได้ดีที่สุดในกรณีนี้
return this
.ObjectContext
.FACILITY_ITEM
.Where(fi => fi.DESCRIPTION.IndexOf(description, StringComparison.OrdinalIgnoreCase)>=0);
คุณสามารถใช้สตริงเปรียบเทียบ
lst.Where(x => string.Compare(x,"valueToCompare",StringComparison.InvariantCultureIgnoreCase)==0);
หากคุณเพียงต้องการตรวจสอบว่ามีแล้วใช้ "ใด ๆ "
lst.Any(x => string.Compare(x,"valueToCompare",StringComparison.InvariantCultureIgnoreCase)==0)
public static bool Contains(this string input, string findMe, StringComparison comparisonType)
{
return String.IsNullOrWhiteSpace(input) ? false : input.IndexOf(findMe, comparisonType) > -1;
}
StringComparison.InvariantCultureIgnoreCaseเพียงทำงานให้ฉัน:
.Where(fi => fi.DESCRIPTION.Contains(description, StringComparison.InvariantCultureIgnoreCase));
สุจริตไม่จำเป็นต้องเป็นเรื่องยาก อาจดูเหมือนว่าในการโจมตี แต่มันไม่ได้ ต่อไปนี้เป็นเคียวรี linq แบบง่าย ๆ ใน C # ที่ทำงานได้ตรงตามที่ร้องขอ
ในตัวอย่างของฉันฉันกำลังทำงานกับรายชื่อบุคคลที่มีคุณสมบัติหนึ่งชื่อ FirstName
var results = ClientsRepository().Where(c => c.FirstName.ToLower().Contains(searchText.ToLower())).ToList();
การทำเช่นนี้จะค้นหาฐานข้อมูลด้วยการค้นหาตัวพิมพ์เล็ก แต่กลับผลลัพธ์ของตัวพิมพ์ใหญ่ทั้งหมด
ใช้วิธีการString.Equals
public IQueryable<FACILITY_ITEM> GetFacilityItemRootByDescription(string description)
{
return this.ObjectContext.FACILITY_ITEM
.Where(fi => fi.DESCRIPTION
.Equals(description, StringComparison.OrdinalIgnoreCase));
}