EF - שאילתא על טבלת המבצעת קשר גומלין של רבים לרבים
-
אתה טועה, הEF מבין אותך מצויין. כל עוד אינך מייצא את תוצאות השאילתה עד לביטויה המלא, הEF מתרגם מעולה שאילתות סבוכות מאוד.
יש כמה אופנים לכתוב את מה שאתה רוצה, למשל:var blogsWith = db.Blogs.Where(x => x.Tags.Any(y => y.id == 1 || y.id == 3)); var blogWithout = blogsWith.Where(x => !x.Tags.Any(y => y.id == 2 || y.id == 4)); Console.WriteLine(blogWithout);
אתה גם יכול לעשות את הטבלה של תג-בלוג למפורשת וככה לתשאל אותה ישירות.
פורסם במקור בפורום CODE613 ב01/06/2017 00:12 (+03:00)
-
@רחמים
איך עושים את זה?var blogs = db.Blogs.Where(x => x.Tags.Any(y => y.id == 1 && y.id == 3 && y.id != 2 && y.id != 4));
ID לעולם לא יכול להיות שווה גם 1 וגם 3, אני צריך שיביא לי את כל הבלוגים, שבין התגים שלהם יש תג אחד עם מזהה 1 ותג אחרעם מזהה 3
פורסם במקור בפורום CODE613 ב01/06/2017 09:26 (+03:00)
-
תודה,
איך באמת EF עובד, על פי איזה כללים? אני רוצה לדעת מראש אם ביטוי LINQ מסויים יהפך לשאילתא כמו שאני רוצה.
אין פה כללים, אם השאילתה מבטאת את מה שביקשת, אתה יכול לסמוך על EF בעיניים עצומות.
אתה רק צריך א. לא להשתמש בביטויים שלא נתמכים לתרגום לSQL, כמו פונקציות מקומיות וכדומה. זה מעיף שגיאה.
ב. לא לייצא את השאילתה לפני סוף התשאול, למשל בדוגמה הקודמת עם תעשה ToList לפני סיום ההתניה זה יהיה פלטור של Linq To Object ולא SQL בצד השרת.פורסם במקור בפורום CODE613 ב01/06/2017 10:55 (+03:00)
-
@דוד ל.ט.
var blogsWith = db.Blogs.Where(x => x.Tags.Any(y => y.id == 1) && x.Tags.Any(y => || y.id == 3));
מצויין [רק צריך למחוק את ||]
כעת אני צריך להטמיע את זה בטופס הסינון שהמשתמשים יוכלו לחפש בלוגים על פי תגים שיש ו/או שאין
השאלה איך אני בונה ביטוי LINQ כזה בצורה דינמית שכמות התגים משתנה וגם כמובן מזהי התגים צריך להגדיר בזמן ריצה.פורסם במקור בפורום CODE613 ב01/06/2017 11:00 (+03:00)
-
אם כוונתך איך לנסח את השאילתה מול ID של תגיות בצורה דינמית, אתה צריך לאחזר את רשימת התגיות הרלוונטיות ואח"כ לעבוד עם Contains בהתנייה. הנה למשל מתודה גמישה לזמן ריצה:
IQueryable<Blog> ByTags(IQueryable<Blog> blogs, IQueryable<Tag> have, IQueryable<Tag> prohibited) { var with = blogs.Where(x => have.All(y => x.Tags.Contains(y))); return with.Where(x => !x.Tags.Any(y => prohibited.Contains(y))); }
קוד מריץ עם הקריטריונים לעיל:
var tagsTrue = db.Tags.Where(x => x.id == 1 || x.id == 3); var tagsFalse = db.Tags.Where(x => x.id == 2 || x.id == 4); var blogs = ByTags(db.Blogs, tagsTrue, tagsFalse); Console.WriteLine(blogs);
פורסם במקור בפורום CODE613 ב01/06/2017 13:05 (+03:00)