Jawaban:
Anda harus mengaktifkannya sesuai dengan cara Anda memikirkannya. Alih-alih melakukan "dalam" untuk menemukan hak pengguna item saat ini di set yang telah ditentukan sebelumnya dari hak pengguna yang berlaku, Anda meminta seperangkat hak pengguna yang telah ditentukan sebelumnya jika mengandung nilai yang berlaku item saat ini. Ini persis cara yang sama Anda akan menemukan item dalam daftar reguler di .NET.
Ada dua cara untuk melakukan ini menggunakan LINQ, satu menggunakan sintaks kueri dan yang lainnya menggunakan sintaks metode. Pada dasarnya, keduanya sama dan dapat digunakan bergantian tergantung pada preferensi Anda:
Sintaks Kueri:
var selected = from u in users
where new[] { "Admin", "User", "Limited" }.Contains(u.User_Rights)
select u
foreach(user u in selected)
{
//Do your stuff on each selected user;
}
Sintaks Metode:
var selected = users.Where(u => new[] { "Admin", "User", "Limited" }.Contains(u.User_Rights));
foreach(user u in selected)
{
//Do stuff on each selected user;
}
Preferensi pribadi saya dalam contoh ini mungkin sintaksis metode karena alih-alih menetapkan variabel, saya bisa melakukan foreach melalui panggilan anonim seperti ini:
foreach(User u in users.Where(u => new [] { "Admin", "User", "Limited" }.Contains(u.User_Rights)))
{
//Do stuff on each selected user;
}
Secara sintaksis ini terlihat lebih rumit, dan Anda harus memahami konsep ekspresi lambda atau delegasi untuk benar-benar mengetahui apa yang terjadi, tetapi seperti yang Anda lihat, ini memadatkan kode dalam jumlah yang wajar.
Semuanya bermuara pada gaya dan preferensi pengkodean Anda - ketiga contoh saya melakukan hal yang sama sedikit berbeda.
Cara alternatif bahkan tidak menggunakan LINQ, Anda dapat menggunakan sintaks metode yang sama menggantikan "di mana" dengan "FindAll" dan mendapatkan hasil yang sama, yang juga akan bekerja di .NET 2.0:
foreach(User u in users.FindAll(u => new [] { "Admin", "User", "Limited" }.Contains(u.User_Rights)))
{
//Do stuff on each selected user;
}
Ini harus mencukupi tujuan Anda. Ini membandingkan dua koleksi dan memeriksa apakah satu koleksi memiliki nilai yang cocok dengan koleksi lainnya
fea_Features.Where(s => selectedFeatures.Contains(s.feaId))
Jika Anda menggunakan VS2008 / .net 3.5, lihat tip Alex James # 8: http://blogs.msdn.com/alexj/archive/2009/03/26/tip-8-writing-where-in-style -queries-using-linq-to-entitas.aspx
Kalau tidak, cukup gunakan metode array.Contains (someEntity.Member).
Saya akan mengikuti Inner Join dalam konteks ini. Jika saya akan menggunakan isi, itu akan berulang 6 kali meskipun jika fakta bahwa hanya ada satu pertandingan.
var desiredNames = new[] { "Pankaj", "Garg" };
var people = new[]
{
new { FirstName="Pankaj", Surname="Garg" },
new { FirstName="Marc", Surname="Gravell" },
new { FirstName="Jeff", Surname="Atwood" }
};
var records = (from p in people join filtered in desiredNames on p.FirstName equals filtered select p.FirstName).ToList();
Misalkan saya memiliki dua objek daftar.
List 1 List 2
1 12
2 7
3 8
4 98
5 9
6 10
7 6
Menggunakan Contains, itu akan mencari setiap item Daftar 1 dalam Daftar 2 yang berarti iterasi akan terjadi 49 kali !!!
Saya juga mencoba untuk bekerja dengan SQL-IN-like hal - permintaan terhadap Model Data Entitas . Pendekatan saya adalah pembangun string untuk menyusun ekspresi OR besar. Itu sangat jelek, tapi aku khawatir itu satu-satunya cara untuk pergi sekarang.
Nah, itu terlihat seperti ini:
Queue<Guid> productIds = new Queue<Guid>(Products.Select(p => p.Key));
if(productIds.Count > 0)
{
StringBuilder sb = new StringBuilder();
sb.AppendFormat("{0}.ProductId = Guid\'{1}\'", entities.Products.Name, productIds.Dequeue());
while(productIds.Count > 0)
{
sb.AppendFormat(" OR {0}.ProductId = Guid\'{1}\'",
entities.Products.Name, productIds.Dequeue());
}
}
Bekerja dengan GUID dalam konteks ini : Seperti yang Anda lihat di atas, selalu ada kata "GUID" di depan GUID jika ada dalam fragmen string kueri. Jika Anda tidak menambahkan ini, ObjectQuery<T>.Where
berikan pengecualian berikut:
Jenis argumen 'Edm.Guid' dan 'Edm.String' tidak kompatibel untuk operasi ini., Hampir sama dengan ekspresi, baris 6, kolom 14.
Menemukan ini di Forum MSDN, mungkin bermanfaat untuk diingat.
Matthias
... menantikan versi .NET dan Entity Framework berikutnya, ketika semuanya menjadi lebih baik. :)
Metode alternatif untuk jawaban BenAlabaster
Pertama-tama, Anda dapat menulis ulang kueri seperti ini:
var matches = from Users in people
where Users.User_Rights == "Admin" ||
Users.User_Rights == "Users" ||
Users.User_Rights == "Limited"
select Users;
Tentu saja ini lebih 'bertele-tele' dan menyusahkan untuk ditulis tetapi berfungsi semua sama.
Jadi jika kita memiliki beberapa metode utilitas yang membuatnya mudah untuk membuat ekspresi LINQ semacam ini, kita akan berada dalam bisnis.
dengan metode utilitas di tempat Anda dapat menulis sesuatu seperti ini:
var matches = ctx.People.Where(
BuildOrExpression<People, string>(
p => p.User_Rights, names
)
);
Ini membangun ekspresi yang memiliki efek yang sama dengan:
var matches = from p in ctx.People
where names.Contains(p.User_Rights)
select p;
Tetapi yang lebih penting sebenarnya bekerja melawan .NET 3.5 SP1.
Berikut adalah fungsi plumbing yang memungkinkan ini:
public static Expression<Func<TElement, bool>> BuildOrExpression<TElement, TValue>(
Expression<Func<TElement, TValue>> valueSelector,
IEnumerable<TValue> values
)
{
if (null == valueSelector)
throw new ArgumentNullException("valueSelector");
if (null == values)
throw new ArgumentNullException("values");
ParameterExpression p = valueSelector.Parameters.Single();
if (!values.Any())
return e => false;
var equals = values.Select(value =>
(Expression)Expression.Equal(
valueSelector.Body,
Expression.Constant(
value,
typeof(TValue)
)
)
);
var body = equals.Aggregate<Expression>(
(accumulate, equal) => Expression.Or(accumulate, equal)
);
return Expression.Lambda<Func<TElement, bool>>(body, p);
}
Saya tidak akan mencoba menjelaskan metode ini, selain mengatakan itu pada dasarnya membangun ekspresi predikat untuk semua nilai menggunakan valueSelector (yaitu p => p.User_Rights) dan ATAU predikat itu bersama-sama untuk membuat ekspresi untuk lengkap predikat
Contoh nyata:
var trackList = Model.TrackingHistory.GroupBy(x => x.ShipmentStatusId).Select(x => x.Last()).Reverse();
List<int> done_step1 = new List<int>() {2,3,4,5,6,7,8,9,10,11,14,18,21,22,23,24,25,26 };
bool isExists = trackList.Where(x => done_step1.Contains(x.ShipmentStatusId.Value)).FirstOrDefault() != null;
Serius? Kalian tidak pernah menggunakan
where (t.MyTableId == 1 || t.MyTableId == 2 || t.MyTableId == 3)
Checks = NumValues * NumRows
. Karena ini adalah perhitungan tipe M * N, jika salah satu kecil, maka waktu untuk melakukan setiap pemeriksaan yang diperlukan juga akan kecil. Saya menambahkan kendala sehingga cjm30305 akan tahu cara mengatur lingkungan pengujian di mana menunjukkan mengapa solusinya buruk.
where new[] { 1, 2, 3 }.Contains(x)
perbandingannya kurang where (x == 1 || x == 2 || x == 3)
?