LINQのは.ToString()メソッドをサポートしていません。 。文字列でない型に対して文字列の比較を使用するのがよいかどうかもわかりません。しかし、すべてが失われるわけではありません。私は、次の解決策を考え出した:
public partial class MyEntity
{
public int ID { get; set; }
public int Type { get; set; }
public string X { get; set; }
}
public class MyContext : DbContext
{
public DbSet<MyEntity> Entities { get; set; }
}
class Program
{
static void Main(string[] args)
{
Database.SetInitializer(new DropCreateDatabaseIfModelChanges<MyContext>());
using (var ctx = new MyContext())
{
if (!ctx.Entities.Any())
{
ctx.Entities.Add(new MyEntity() { ID = 1, Type = 2, X = "ABC" });
ctx.SaveChanges();
}
Console.WriteLine(DoesColValueExist(ctx.Entities, e => e.X, "aBc"));
Console.WriteLine(DoesColValueExist(ctx.Entities, e => e.X, "aBcD"));
Console.WriteLine(DoesColValueExist(ctx.Entities, e => e.Type, 2));
Console.WriteLine(DoesColValueExist(ctx.Entities, e => e.Type, 5));
}
}
private static bool DoesColValueExist<TEntity, TProperty>(IQueryable<TEntity> dataToSearchIn, Expression<Func<TEntity, TProperty>> property, TProperty colValue)
{
var memberExpression = property.Body as MemberExpression;
if (memberExpression == null || !(memberExpression.Member is PropertyInfo))
{
throw new ArgumentException("Property expected", "property");
}
Expression left = property.Body;
Expression right = Expression.Constant(colValue, typeof(TProperty));
if (typeof(TProperty) == typeof(string))
{
MethodInfo toLower = typeof(string).GetMethod("ToLower", new Type[0]);
left = Expression.Call(left, toLower);
right = Expression.Call(right, toLower);
}
Expression searchExpression = Expression.Equal(left, right);
var lambda = Expression.Lambda<Func<TEntity, bool>>(Expression.Equal(left, right), new ParameterExpression[] { property.Parameters.Single() });
return dataToSearchIn.Where(lambda).Any();
}
}
それについての素晴らしい事は、それが文字列ベースのソリューションよりも安全でより多くの種類があるということです - パラメータの値は、プロパティの値と同じである必要があります。このプロパティは、最初のパラメータとして渡されたIQueryable'1のジェネリック型であるエンティティのメンバでなければなりません。もう1つの便利なことは、このメソッドに対してコーディングするときに、intellisenseが、2番目のパラメータのラムダ式の入力を開始するときに、エンティティのメンバーを表示するということです。メソッド自体で、プロパティの値と要求された値の両方で.ToLower()を呼び出すと、大文字と小文字を区別しないようにするために、文字列型の例外が追加されました。非文字列タイプの場合、値は「そのまま」、すなわち何も変更されずに比較される。 上記の例は完了です。コンソールアプリケーションプロジェクトにコピーして貼り付けることができます(EntityFramework.dllを参照する必要があります)。 これが役立つことを願っています。プロパティが文字列であるならば、それはToString()
メソッドを呼び出すことはありませんが、基本的に
private static bool DoesColValueExist<T>(IQueryable dataToSearchIn, string colName, string colValue)
{
int noOfClients = 1;
Type type = typeof(T);
if (colValue != "" && colName != "")
{
var property = type.GetProperty(colName);
var parameter = Expression.Parameter(type, "p");
var propertyAccess = Expression.MakeMemberAccess(parameter, property);
Expression left = property.PropertyType == typeof(string) ? propertyAccess : Expression.Call(propertyAccess, typeof(object).GetMethod("ToString", System.Type.EmptyTypes));
left = Expression.Call(left, typeof(string).GetMethod("ToLower", System.Type.EmptyTypes));
Expression right = Expression.Constant(colValue.ToLower(), typeof(string));
MethodInfo method = typeof(string).GetMethod("Equals", new[] { typeof(string) });
Expression searchExpression = Expression.Call(left, method, right);
MethodCallExpression whereCallExpression = Expression.Call(
typeof(Queryable),
"Where",
new Type[] { type },
dataToSearchIn.Expression,
Expression.Lambda<Func<T, bool>>(searchExpression, new ParameterExpression[] { parameter }));
var searchedData = dataToSearchIn.Provider.CreateQuery(whereCallExpression);
noOfClients = searchedData.Cast<T>().Count();
if (noOfClients == 0)
return false;
else
return true;
}
return true;
}
:
どのような列の種類ですか?彼らは弦ではありませんか? 'colValue'を適切な型に変換して比較するのはどうですか? L2Eがサポートする操作は、設計によって制限されています。 –
LINQKitのDynamicQueryまたはPredicateBuilder(以前の@ http://weblogs.asp.net/scottgu/archive/2008/01/07/dynamic-linq-part)を見たいと思うかもしれないのか疑問に思っています。 -1-using-linq-dynamic-query-library.aspxと後者@ http://www.albahari.com/nutshell/linqkit.aspx –