2

nvarchar文字列 ( ) 列に書式設定された値を含むテーブルがあるとします。これらの値は、const 記号 (セミコロン;) で区切られた文字列であると想定されています。例えば、

12;0;5;dog //four values separated by a semi-colon

また

053 //if there is only one value, no semi-colon at the end

区切り記号は常に区切り記号であり、値の一部にすることはできません。

そのテーブルに、指定された項目の少なくとも 1 つを含む値のリストがその列にある行が既に存在するかどうかを確認する必要があります。言い換えれば、私は値のリストを持っています:

List<string> list = new List<string>() { "somevalue1", "somevalue2" };

セパレーター:

string separator = ";";

そして、これを行う linq-to-sql クエリを作成する必要があります。

select ... from sometable
where Value='somevalue1' or Value like 'somevalue1;%' or
      Value like '%;somevalue1' or Value like '%;somevalue1;%'

   or Value='somevalue2' or Value like 'somevalue2;%' or 
      Value like '%;somevalue2' or Value like '%;somevalue2;%'

検索された値のいずれかに他の値が含まれている可能性があることに注意してください。つまり、正確5に を検索している可能性がありますが、一部の行には が含まれている可能性があります1;15;55。そのような行は一致してはなりません。while...;5;...または just 5、 または5;...、 または...;5が一致します。

linq-to sql を使用して、次の種類のクエリを実行する方法を知っています。

select ... from sometable where (... or ... or ...) and (... or ...) ...

あれは

IQueryable<SomeTable> query = dc.SomeTable;
foreach (string l in list)
{
    string s = l;
    query = query.Where(b => b.Value.StartsWith(s + separator) ||
                             b.Value.EndsWith(separator + s) ||
                             b.Value.Contains(separator + s + separator) ||
                             b.Value.Equals(s));
}
if (query.Any()) {/*...*/}

明らかに、結果のSQLクエリでWhereステートメントが結合されますが、どこでも必要です。ANDOR

C# コード内で必要なクエリを取得する方法はありますか? または、手書きのクエリとDataContext.ExecuteQuery Methodを使用してこれを行う唯一の方法ですか?

4

2 に答える 2

4
public static Expression<Func<T, bool>> OrTheseFiltersTogether<T>(
  this IEnumerable<Expression<Func<T, bool>>> filters)
{
    Expression<Func<T, bool>> firstFilter = filters.FirstOrDefault();
    if (firstFilter == null)
    {
        Expression<Func<T, bool>> alwaysTrue = x => true;
        return alwaysTrue;
    }

    var body = firstFilter.Body;
    var param = firstFilter.Parameters.ToArray();
    foreach (var nextFilter in filters.Skip(1))
    {
        var nextBody = Expression.Invoke(nextFilter, param);
        body = Expression.OrElse(body, nextBody);
    }
    Expression<Func<T, bool>> result = Expression.Lambda<Func<T, bool>>(body, param);
    return result;
}

したがって、入力セットからフィルターのリストを簡単に作成できます。

List<string> list = new List<string>() { "somevalue1", "somevalue2" };
List<Expression<Func<SomeTable, bool>>> equalsFilters = list
  .Select(s => row => row.Value == s).ToList();
List<Expression<Func<SomeTable, bool>>> startsWithFilters = list
  .Select(s => row => row.Value.StartsWith(s + ";")).ToList();
List<Expression<Func<SomeTable, bool>>> endsWithFilters = list
  .Select(s => row => row.Value.EndsWith(";" + s).ToList();
List<Expression<Func<SomeTable, bool>>> middleFilters = list
  .Select(s => row => row.Value.Contains(";" + s + ";")).ToList();

Expression<Func<SomeTable, bool>> theFilter = OrTheseFiltersTogether(
  equalsFilters.Concat(startsWithFilters).Concat(endsWithFilters).Concat(middleFilters)
);

query = query.Where(theFilter);
于 2013-01-28T07:19:24.010 に答える
3

私はUNIONあなたのニーズに合うと思います:

IQueryable<SomeTable> baseQuery = dc.SomeTable;
IQueryable<SomeTable> query = new List<SomeTable>().AsQueryable();
foreach (string l in list)
{
    string s = l;

    query.Union(baseQuery.Where(b => b.Value.StartsWith(s + separator) ||
                             b.Value.EndsWith(separator + s) ||
                             b.Value.Contains(separator + s + separator) ||
                             b.Value.Equals(s)));
}
if (query.Any()) {/*...*/}
于 2013-01-28T07:04:33.057 に答える