回答:
あなたはそれについて考えている方法の観点からそれを頭に向ける必要があります。「in」を実行して、事前定義された一連の適用可能なユーザー権限で現在のアイテムのユーザー権限を見つける代わりに、事前定義された一連のユーザー権限に現在のアイテムの適用可能な値が含まれている場合は、それを要求します。これは、.NETの通常のリストでアイテムを見つける方法とまったく同じです。
LINQを使用してこれを行う方法は2つあり、1つはクエリ構文を使用し、もう1つはメソッド構文を使用します。基本的に、これらは同じであり、好みに応じて互換的に使用できます。
クエリ構文:
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;
}
メソッド構文:
var selected = users.Where(u => new[] { "Admin", "User", "Limited" }.Contains(u.User_Rights));
foreach(user u in selected)
{
//Do stuff on each selected user;
}
このインスタンスでの個人的な好みは、変数を割り当てる代わりに、次のように匿名呼び出しよりもforeachを実行できるため、メソッド構文になる可能性があります。
foreach(User u in users.Where(u => new [] { "Admin", "User", "Limited" }.Contains(u.User_Rights)))
{
//Do stuff on each selected user;
}
構文的にはこれはより複雑に見え、何が起こっているのかを実際に理解するにはラムダ式またはデリゲートの概念を理解する必要がありますが、ご覧のとおり、これによりコードがかなり凝縮されます。
それはすべてあなたのコーディングスタイルと好みに帰着します-私の3つの例はすべて同じことをわずかに異なって行います。
別の方法ではLINQも使用せず、「where」を「FindAll」で置き換える同じメソッド構文を使用して同じ結果を得ることができます。これは.NET 2.0でも機能します。
foreach(User u in users.FindAll(u => new [] { "Admin", "User", "Limited" }.Contains(u.User_Rights)))
{
//Do stuff on each selected user;
}
VS2008 / .net 3.5を使用している場合は、Alex Jamesのヒント#8を参照してください。 http://blogs.msdn.com/alexj/archive/2009/03/26/tip-8-writing-where-in-style -queries-using-linq-to-entities.aspx
それ以外の場合は、array.Contains(someEntity.Member)メソッドを使用してください。
このコンテキストでは、内部結合に行きます。containsを使用した場合、一致が1つしかないにもかかわらず、6回反復されます。
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();
2つのリストオブジェクトがあるとします。
List 1 List 2
1 12
2 7
3 8
4 98
5 9
6 10
7 6
Containsを使用すると、リスト2の各リスト1アイテムが検索されます。つまり、反復が49回発生します!!!
また、SQL-INのようなものを操作しようとしました- エンティティデータモデルに対するクエリ。私のアプローチは、大きなOR式を作成する文字列ビルダーです。それはひどく醜いですが、今それが唯一の方法だと思います。
さて、それはこのようになります:
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());
}
}
このコンテキストでのGUIDの操作:上記のように、クエリ文字列フラグメントでは、GUID自体の前に常に「GUID」という単語があります。これを追加しないとObjectQuery<T>.Where
、次の例外がスローされます。
引数の型 'Edm.Guid'および 'Edm.String'は、この操作と互換性がありません。ほぼ等しい式、6行目、14列目。
これはMSDNフォーラムで見つかりました。覚えておくと役に立ちます。
マティアス
...次のバージョンの.NETおよびEntity Frameworkを楽しみにしています。:)
BenAlabasterの答えの代替方法
まず、次のようにクエリを書き直すことができます。
var matches = from Users in people
where Users.User_Rights == "Admin" ||
Users.User_Rights == "Users" ||
Users.User_Rights == "Limited"
select Users;
確かに、これはより「冗長」で書くのは面倒ですが、まったく同じように機能します。
したがって、この種のLINQ式を簡単に作成できるユーティリティメソッドがあれば、ビジネスに携わることになります。
ユーティリティメソッドを使用すると、次のように記述できます。
var matches = ctx.People.Where(
BuildOrExpression<People, string>(
p => p.User_Rights, names
)
);
これにより、以下と同じ効果を持つ式が作成されます。
var matches = from p in ctx.People
where names.Contains(p.User_Rights)
select p;
しかし、これは.NET 3.5 SP1に対して実際に機能します。
これを可能にする配管機能は次のとおりです。
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);
}
私はこのメソッドを説明するつもりはありませんが、本質的には、valueSelector(p => p.User_Rights)を使用してすべての値の述語式を構築し、それらの述語をORして完全な式を作成します述語
出典:http : //blogs.msdn.com/b/alexj/archive/2009/03/26/tip-8-writing-where-in-style-queries-using-linq-to-entities.aspx
実際の例:
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;
マジ?あなたは人々が使ったことがない
where (t.MyTableId == 1 || t.MyTableId == 2 || t.MyTableId == 3)
Checks = NumValues * NumRows
。これはM * Nタイプの計算であるため、どちらかが小さければ、必要な各チェックを実行する時間も短くなります。制約を追加して、cjm30305が彼のソリューションが貧弱である理由を示すテスト環境のセットアップ方法を認識できるようにしました。
where new[] { 1, 2, 3 }.Contains(x)
比較が少ないということwhere (x == 1 || x == 2 || x == 3)
ですか?