web-dev-qa-db-ja.com

C#Dynamic Linq:Where句に "Like"を実装する

それで、私のデータのための一般的なソーターを作りたいです。 valueを含むデータのみを抽出するデータベースからデータを取得するこのコードがあります。

_using System.Linq.Dynamic;

public static IQueryable<object> SortList(string searchString, Type modelType, 
    IQueryable<object> model)
{
    ....

    string toStringPredicate = type == typeof(string) ? propertyName + 
        ".Contains(@0)" : propertyName + ".ToString().Contains(@0)";
    model = model.Where(propertyName + " != NULL AND " + toStringPredicate, value);
}
_

モデルはこれです:

_public class ManageSubscriberItems
{
    public int? UserId { get; set; }
    public string Email { get; set; }
    public Guid SubscriberId { get; set; }
}
_

私が電話するとき:

_models = (IQueryable<ManageSubscriberItems>)EcommerceCMS.Helpers.FilterHelper
    .SortList(searchString, typeof(ManageSubscriberItems), models);

if(models.Any())
_

それはこのエラーを投げます:

「LINQ to Entitiesはメソッド 'System.String ToString()'メソッドを認識せず、このメソッドはストア式に変換できません。」


編集

問題を見つけましたが、まだ修正できません。したがって、プロパティがstringでない場合、.ToString().Contains()を呼び出すとエラーがスローされます。

_model = model.Where(propertyName + " != NULL AND " + propertyName + 
    ".ToString().Contains(@0)", value);
_

私が欲しいのは、クエリにLIKEを実装することです。誰か助けてもらえますか?

10
Alvin Stefanus

System.Linq.Dynamic.CoreEF Coreと共に使用する場合、使用するオプションがあります

var q = context.Cars.Where(config, "DynamicFunctions.Like(Brand, \"%a%\")");

例については、このリンクを参照してください: https://github.com/StefH/System.Linq.Dynamic.Core/blob/6fc7fcc43b248940560a0728c4d181e191f9eec1/src-console/ConsoleAppEF2.1.1/Program.cs#L117

そして、私は実際のデータベースに接続するlinqpadでテストしたところ、このようなコードはうまくいきますか?

var result1 = Entity1s.Where("Url != NULL AND it.Url.Contains(@0)", "e");


[UPDATE 2019-04-17]]

タイプがわからない場合は、objectにキャストしてから、stringにキャストできます

コード:

var r = Entity1s.Select("string(object(Rating))").Where("Contains(@0)", "6");
9
Stef Heyenrath

したがって、ここでの問題はIQueryable[〜#〜] sql [〜#〜] C#にないサーバーで発生するということです... so [〜 #〜] sql [〜#〜]サーバーは。toString()メソッドについて何も知りません。 so =>およびLike演算子それは文字列に対して自己動作します。したがって、SQLサーバーではnvarcharおよびvarcharデータ型です。あなたがあなたの問題とあなたが達成したいことについてもっと教えてくれるなら、私はあなたにそれを達成する方法の例を与えることができます。サンプルを行うことができます。

4

データベースで実行でき、文字列を操作できる「Like」がすでにLinqにあります。これは「IndexOf」と呼ばれます。

 ((IQueryable)model).Where(m => m.Property.IndexOf(searchString) == 1);

MSDNによると: IndexOf(string)

'その文字列が見つかった場合、値のゼロベースのインデックス位置。見つからなかった場合は-1。値が空の場合、戻り値は0です。 '

0
Diogo Neves

それで、私のデータのための一般的なソーターを作りたいです。

'invoke issue' を修正する代わりに、一般的な方法は次のようなジェネリックを使用する必要があります

public static IQueryable<T> OrderBy<T>(this IQueryable<T> source, 
                                       string property,
                                       bool asc = true) where T : class
{
    //STEP 1: Validate MORE!
    var searchProperty = typeof(T).GetProperty(property);
    if (searchProperty == null) throw new ArgumentException("property");

     ....

    //STEP 2: Create the OrderBy property selector
    var parameter = Expression.Parameter(typeof(T), "o");
    var selectorExpr = Expression.Lambda(Expression.Property(parameter, property), parameter)        

    //STEP 3: Update the IQueryable expression to include OrderBy
    Expression queryExpr = source.Expression;
    queryExpr = Expression.Call(typeof(Queryable), asc ? "OrderBy" : "OrderByDescending",
                                  new Type[] { source.ElementType, searchProperty.PropertyType },
                                 queryExpr, 
                                selectorExpr);

    return source.Provider.CreateQuery<T>(queryExpr);
}

データの「列のソート」を行うために通常使用されるプロパティ名文字列と方向を持っています。

次は関係述語が来ており、「Linq.Dynamic」はゼロから行うと合理的であるように見えますが、一般的で標準的な形式 exists があります。

0
valerysntx