gpt4 book ai didi

c# - 尝试使用 LINQ 以数据库字段作为参数获取不同的值

转载 作者:行者123 更新时间:2023-11-30 21:27:26 24 4
gpt4 key购买 nike

我正在尝试使用 Linq 查询从 MsSQL 数据库中选择不同的值并将数据库字段作为标准传递,但它给了我错误。

如果一个表有如下数据:

Name | Age | Class | school
----------------------------
Anna, 23, grade 2, Havard
Kendricks,34, grade 2, Havard
Vikander, 27, grade 3, Covenant
Hathaway, 18, grade1, Covenant
Gemma, 23, grade 4, Bowen
Jolie, 23, grade 5, Havard
Arteton, 24, grade 1, Bayero
Ana Armas 30, grade 2, Coventry

现在,我试图从上表中通过传递“学校”或“类(class)”或更多字段来检索数据,然后返回基于这些字段的不同值。我该怎么做?

// filterParam - is the field(class, school)
// then how do I select the distinct values...

下面是我的代码:

  public IEnumerable<ScbDataInfo> GetScbOptionsByFilter(string filterParam) {
using (SRSContext entityContext = new SRSContext()) {

var query = (from e in entityContext.Set<ScbDataInfo>()

where e[filterParam] == searchParam //i passed it here
orderby e.RefNo, e.datepmt
select e).Distinct();

return query.ToArray();

}
}

最佳答案

这是一些代码,我前段时间从 DataTables.Queryable 拼凑而成的通过 Alexander Krutov行货MIT :

这通过表达式工作,在您调用 ToArray 之前不需要具体化您的数据。由你自己:

/// <summary>
/// Creates predicate expression like
/// <code>(T t) => t.SomeProperty.Contains("Constant")</code>
/// where "SomeProperty" name is defined by <paramref name="stringConstant"/> parameter, and "Constant" is the <paramref name="stringConstant"/>.
/// If property has non-string type, it is converted to string with <see cref="object.ToString()"/> method.
/// </summary>
/// <typeparam name="T">Data type</typeparam>
/// <param name="propertyName">Property name</param>
/// <param name="stringConstant">String constant to construnt the <see cref="string.Contains(string)"/> expression.</param>
/// <param name="caseInsensitive">Case insenstive Contains Predicate?</param>
/// <returns>Predicate instance</returns>
public static Expression<Func<T, bool>> BuildStringContainsPredicate<T>(string propertyName, string stringConstant, bool caseInsensitive)
{
var type = typeof(T);
var parameterExp = Expression.Parameter(type, "e");
var propertyExp = BuildPropertyExpression(parameterExp, propertyName);

Expression exp = propertyExp;

// if the property value type is not string, it needs to be casted at first
if (propertyExp.Type != typeof(string))
{
// If we have an Enum, the underlying Entity Framework Provider can not translate the Enum to SQL.
// Therefore we converting it first to the underlying primitive type (byte, int16, int32, int64 etc)
//Todo: Sideeffects beobachten
//Todo: Evtl möglichkeit finden Display Attribute zu implementieren um eine String Suche zu ermöglichen?
//Todo: Notwendigkeit in NET Core 2.1 überprüfen
if (propertyExp.Type.IsEnum)
{
exp = Expression.Convert(exp, Enum.GetUnderlyingType(propertyExp.Type));
}

exp = Expression.Call(exp, ObjectToString);
}

// call ToLower if case insensitive search
if (caseInsensitive)
{
exp = Expression.Call(exp, StringToLower);
stringConstant = stringConstant.ToLower();
}
var someValue = Expression.Constant(stringConstant, typeof(string));
var containsMethodExp = Expression.Call(exp, StringContains, someValue);
return Expression.Lambda<Func<T, bool>>(containsMethodExp, parameterExp);
}

/// <summary>
/// Builds the property expression from the full property name.
/// </summary>
/// <param name="param">Parameter expression, like <code>e =></code></param>
/// <param name="propertyName">Name of the property</param>
/// <returns>MemberExpression instance</returns>
private static MemberExpression BuildPropertyExpression(ParameterExpression param, string propertyName)
{
var parts = propertyName.Split('.');
Expression body = param;
foreach (var member in parts)
{
body = Expression.Property(body, member);
}
return (MemberExpression)body;
}

/// <summary>
/// <see cref="object.ToString()"/> method info.
/// Used for building search predicates when the searchable property has non-string type.
/// </summary>
private static readonly MethodInfo ObjectToString = typeof(object).GetMethod(nameof(ToString));


/// <summary>
/// <see cref="string.ToLower()"/> method info.
/// Used for conversion of string values to lower case.
/// </summary>
private static readonly MethodInfo StringToLower = typeof(string).GetMethod(nameof(string.ToLower), new Type[] { });

/// <summary>
/// <see cref="string.Contains(string)"/> method info.
/// Used for building default search predicates.
/// </summary>
private static readonly MethodInfo StringContains = typeof(string).GetMethod(nameof(string.Contains), new[] { typeof(string) });

这将创建一个过滤器表达式,其中 propertyName是列,stringConstant搜索值和 bool,如果搜索应该区分大小写或不区分大小写。 T是你的类型 IQueryable<T> .

PredicateBuilder 你可以这样做:

public static IQueryable<T> FilterColumns(this IQueryable<T> query, IEnumerable<string> columns, string searchValue)
{
Expression<Func<T, bool>> predicate = null;
foreach (var column in columns)
{
var expr = BuildStringContainsPredicate<T>(column,
searchValue, false);
predicate = predicate == null ? PredicateBuilder.Create(expr) : predicate.Or(expr);
}
return query.Where(predicate);
}

这提供了一个扩展方法,因此包含的类必须是静态的。

现在您可以执行以下操作:

entityContext.ScbDataInfos
.FilterColumns(columnNames, searchValue)
.OrderBy(e => e.RefNo)
.ThenBy(e => e.datepm)
.Distinct()
.ToArray();

关于c# - 尝试使用 LINQ 以数据库字段作为参数获取不同的值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57729824/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com