linq ที่มีรายการใด ๆ ในรายการ


117

เมื่อใช้ linq ฉันจะเรียกข้อมูลรายการที่รายการคุณสมบัติตรงกับรายการอื่นได้อย่างไร

ใช้ตัวอย่างง่ายๆนี้และรหัสเทียม:

List<Genres> listofGenres = new List<Genre>() { "action", "comedy" });   
var movies = _db.Movies.Where(p => p.Genres.Any() in listofGenres);

คำตอบ:


202

ดูเหมือนว่าคุณต้องการ:

var movies = _db.Movies.Where(p => p.Genres.Intersect(listOfGenres).Any());

ฉันพยายามใช้คำค้นหานี้สำหรับช่องค้นหามันค้นหาอักขระใด ๆ ในคอลัมน์ Person_Name ฉันได้รับข้อผิดพลาดนี้: 'DbIntersectExpression ต้องการอาร์กิวเมนต์ที่มี ResultTypes คอลเลกชันที่เข้ากันได้' ดังนั้นฉันจึงลอง.StartWith, .EndsWith, .Containsจากที่นี่มันใช้งานได้ แต่สิ่งที่สามารถทำได้เพื่อใช้แบบสอบถามของคุณ
shaijut

@stom: เราไม่ได้มีข้อมูลเพียงพอที่จะช่วยให้คุณกับที่ - คุณควรถามคำถามใหม่ที่มีจำนวนมากบริบทอื่น ๆ
Jon Skeet

@JonSkeet ฉันมักจะใช้วิธีการประกอบด้วยสำหรับการสืบค้นประเภทนี้ ฉันอยากรู้เมื่อเห็นคำตอบของคุณและตรวจสอบการใช้งานภายในและพบว่า Intersect ใช้ Set คุณช่วยบอกความแตกต่างของประสิทธิภาพระหว่างสองวิธีนี้ได้ไหม
เกิดใหม่

6
@Rebornx: การใช้Containsซ้ำ ๆ จะจบลงเป็นการดำเนินการ O (x * y) ตามเวลา แต่ O (1) ในช่องว่างโดยที่ x คือขนาดของคอลเล็กชันแรกและ y คือขนาดของวินาที การใช้Intersectคือ O (x + y) ตามเวลา แต่ O (y) ในอวกาศ - สร้างแฮชเซ็ตจากคอลเล็กชันที่สองซึ่งทำให้ตรวจสอบการรวมสำหรับรายการใด ๆ จากคอลเล็กชันแรกได้อย่างรวดเร็ว ดูcodeblog.jonskeet.uk/2010/12/30/…สำหรับรายละเอียด
Jon Skeet

1
@SteveBoniface: ฉันจะไม่คาดหวังอย่างนั้นไม่ ฉันคาดหวังว่ารุ่นหลังจะเร็วขึ้นเล็กน้อยเนื่องจากมีทิศทางน้อยลง
Jon Skeet



3

ฉันเดาว่ามันเป็นไปได้เช่นนี้?

var movies = _db.Movies.TakeWhile(p => p.Genres.Any(x => listOfGenres.Contains(x));

"TakeWhile" แย่กว่า "Where" ในแง่ของประสิทธิภาพหรือความชัดเจนหรือไม่?


TakeWhileเป็นฟังก์ชันที่แตกต่างกัน - จะหยุดการทำซ้ำเมื่อไม่พบสิ่งที่ตรงกัน
D Stanley

1

หรือแบบนี้

class Movie
{
  public string FilmName { get; set; }
  public string Genre { get; set; }
}

...

var listofGenres = new List<string> { "action", "comedy" };

var Movies = new List<Movie> {new Movie {Genre="action", FilmName="Film1"},
                new Movie {Genre="comedy", FilmName="Film2"},
                new Movie {Genre="comedy", FilmName="Film3"},
                new Movie {Genre="tragedy", FilmName="Film4"}};

var movies = Movies.Join(listofGenres, x => x.Genre, y => y, (x, y) => x).ToList();
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.