查询其中一列包含值的最佳方法是什么?
这是我的代码:
public JsonResult FindCustomer(string value)
{
var result= new SelectList(db.Customers.Where(t => (t.PersonalMail.Contains(value) ||
t.BusinessMail.Contains(value)
|| t.ContactName.Contains(value) ||
t.BusinessName.Contains(value) || t.Phone.Contains(value) ||
t.DirectPhone.Contains(value)), "ID", "PersonalMail");
return Json(jj);
}
也许有可能做到这样的事情:
var result= new SelectList(db.Customers.Where(t => (Each column).Contains(value)), "ID", "PersonalMail");
答案 0 :(得分:1)
public JsonResult FindCustomer(string value)
{
var Customers = db.Customers.ToList();
var result = new SelectList(db.Customers.Where(t =>
t?.GetType().GetProperties().Any(x => //for all columns of a row where...
(x.PropertyType==typeof(string)) && // it does have the same type
x.GetValue(t, null) != null && // the value should not be null
x.GetValue(t, null).ToString().Contains(value)) // the value should be equal
?? false), // if t is null, than skip it
"ID", "PersonalMail");
return Json(jj);
}
会做的伎俩。如果您确实想要排除某些列,请将它们添加到ANY
子句:
.Any(x => x.GetValue(t, null) != null && !x.Name.Equals("BusinessMail") && (x.PropertyType==typeof(string)) && x.GetValue(t, null).ToString().Contains(value))
要选择包含该值的第一个属性的值,请在"PersonalMail")
之后添加以下内容:
.Select(t=>t.GetType().GetProperties().First(x=> // get the first porperty
x.GetValue(t, null).Equals(value) // where the value equals the searched one
).GetValue(t, null)); // And select the value of that property.
如果您确实要获取属性而不是值,请删除.GetValue(t, null)
。您还可以使用Where
代替Any
,并返回包含该值的所有属性的列表。 (注意,它将返回一个用PropertyInfo填充的集合!)
答案 1 :(得分:0)
不确定它更好还是值得,但(假设所有类型相同)你可以这样做:
var result =
new SelectList (
db
.Customers
.Where (t => new[] {
t.PersonalMail,
t.BusinessMail,
t.ContactName,
t.BusinessName
t.Phone,
t.DirectPhone
}.Any (s => s.Contains (value))), "ID", "PersonalMail");
但是我觉得最好在某个地方(可能在t
来自的类中)有一个方法,它可以利用像
bool CheckContains (TypeOfT t, string value)
{
return t.PersonalMail.Contains (value)
|| t.BusinesMail.Contains (value)
|| t.ContactName.Contains (value)
|| t.BusinessName.Contains (value)
|| t.Phone.Contains (value)
|| t.DirectPhone.Contains (value);
}
// ...
var result = new SelectList (db.Customers.Where (t => CheckContains (t, value)), "ID", "PersonalMail");
答案 2 :(得分:0)
您可以使用让
var result = new SelectList((from t in db.Customers
let values = new[]
{
t.PersonalMail,
t.BusinessMail,
t.ContactName,
t.BusinessName,
t.Phone,
t.DirectPhone
}
where values.Any(v => v.Contains(value))
select t), "ID", "PersonalMail");
答案 3 :(得分:0)
如果你想要它简短,你可以试试这个:
db.Customers.Where(t => (t.PersonalMail + t.BusinesMail + t.ContactName).Contains(value)
但这可能效率不高。
答案 4 :(得分:0)
您可以使用反射来构建适当的表达式。添加以下using
语句。
using System.Linq.Expressions;
using static System.Linq.Expressions.Expression;
这样的事情:
static Expression<Func<Customer, bool>> ExpressionBuilder(string phrase) {
//We are trying to set up the equivalent of this:
// x => x.PersonMail == phrase || x.BusinessMail == phrase || x.ContanctName == ...
//The lambda expression has a single parameter
// x =>
//In the body of the lambda, for each string property on Customer, we want to call the
//property on the parameter, and then check if it is equal to the phrase
// x.PersonMail == phrase
//We then want to combine each result into an ||
// x.PersonMail == phrase || x.BusinessMail == phrase ...
//Define an expression representing the parameter
var prm = Parameter(typeof(Customer));
//Get all the string properties
var stringProps = typeof(Customer).GetProperties()
.Where(x => x.PropertyType == typeof(string))
//For each property, create an expression that represents reading the property, and
//comparing it to phrase as a constant (as if we had written the literal value into
//the query)
.Select(x => Equal(MakeMemberAccess(prm, x), Constant(phrase)));
//Combine the equals expressions using ||
Expression expr = stringProps.Aggregate((prev, x) => Or(prev, x));
//Wrap the body in a lambda expression of the appropriate type
return Lambda<Func<Customer, bool>>(expr, prm);
}
然后,您可以这样称呼它:
//qry is IQueryable<Customer>
qry = qry.Where(ExpressionBuilder("test"));