对IQueryable <object>进行HasProperty检查-C#.NetCore 2.2

时间:2018-11-09 15:52:56

标签: c# linq asp.net-core entity-framework-core

我有一个方法可以将动态linq(System.Linq.Dynamic.Core)附加到IQueryable:

public static IQueryable<object> SearchBySecurityList(List<SecurityListFilter> caSecurityFilterList, IQueryable<object> qry)

public class SecurityListFilter
{
    public string FooOne{ get; set; }
    public string FooTwo { get; set; }
    public string FooThree { get; set; }
    public string FooFour { get; set; }
    public string FooFive { get; set; }
}

该方法通过将where字符串简单地绑定到qry来在方法末尾构建一个where字符串:

return qry.Where(whereClause, paramList.ToArray());

问题在于某些对象(作为“ qry”传递)没有在SecurityListFilter对象上具有某些属性。因此,可以说我将IQueryable qry传递到我的方法中,并且FooFour属性不存在。我将收到一条错误消息,指出该属性不存在。

我的问题是如何进行属性检查以查看IQueryable 中是否存在FooFour?

我已经尝试过了,但是总是错误的:

if (qry.HasProperty("FooFour") != false)

1 个答案:

答案 0 :(得分:0)

我不确定是否有更好的答案,但这目前对我有用。 在方法开始时,我这样做:

PropertyInfo[] props = qry.GetType().GetProperties();

然后,稍后在我需要检查属性是否存在时:

if(!props.HasProperty("SomePropertyOne") || !props.HasProperty("SomePropertyTwo"))

编辑1: @StriplingWarrior-这是我目前正在使用的方法。敏感名称已被删除,并以“ Blah”代替。

public static IQueryable<object> SearchBySecurityList(List<SecurityListFilter> caSecurityFilterList, IQueryable<object> qry, string companySearch, string fpSearch, string poSearch, string controlOwnerSearch, string carSearch)
    {
        string whereClause = "";
        int paramCount = -1;
        int loopCount = 1;
        PropertyInfo[] props = qry.GetType().GetProperties();
        List<string> paramList = new List<string>();
        List<string> finalList = new List<string>();

        foreach (var i in caSecurityFilterList)
        {
            if (loopCount > 1)
            {
                whereClause = whereClause + " || ";
            }

            string innerWhere = "(";
            if (!string.IsNullOrWhiteSpace(i.CompanyName))
            {
                if(!props.HasProperty("Company") || !props.HasProperty("CompanyName"))
                {
                    paramList.Add(i.CompanyName);
                    paramCount++;
                    innerWhere = innerWhere + $"{companySearch} == @{paramCount}";
                }
            }
            if (!string.IsNullOrWhiteSpace(i.BlahProcessName))
            {
                if (!props.HasProperty("BlahProcess") || !props.HasProperty("BlahProcessName"))
                {
                    paramList.Add(i.BlahProcessName);
                    paramCount++;
                    if (innerWhere.Length > 1) innerWhere = innerWhere + " and ";
                    innerWhere = innerWhere + $"{fpSearch} == @{paramCount}";
                }
            }
            if (!string.IsNullOrWhiteSpace(i.ProcessOwner))
            {
                if (!props.HasProperty("ProcessOwner"))
                {
                    paramList.Add(i.ProcessOwner);
                    paramCount++;
                    if (innerWhere.Length > 1) innerWhere = innerWhere + " and ";
                    innerWhere = innerWhere + $"{poSearch} == @{paramCount}";
                }
            }
            if (!string.IsNullOrWhiteSpace(i.ControlOwner))
            {
                if (!props.HasProperty("ControlOwner"))
                {
                    paramList.Add(i.ControlOwner);
                    paramCount++;
                    if (innerWhere.Length > 1) innerWhere = innerWhere + " and ";
                    innerWhere = innerWhere + $"{controlOwnerSearch} == @{paramCount}";
                }
            }
            if (!string.IsNullOrWhiteSpace(i.CAR))
            {
                if (!props.HasProperty("BLAH"))
                {
                    paramList.Add(i.CAR);
                    paramCount++;
                    if (innerWhere.Length > 1) innerWhere = innerWhere + " and ";
                    innerWhere = innerWhere + $"{carSearch} == @{paramCount}";
                }
            }
            innerWhere = innerWhere + ")";

            whereClause = whereClause + innerWhere;//This should get me something like "() || () || ()"
            loopCount++;
        }

        return qry.Where(whereClause, paramList.ToArray());
    }

然后我这样称呼它:

IQueryable<MYENTITY> qry = (IQueryable<MYENTITY>)StaticMethod.SearchBySecurityList(
                    input.SecurityFilterList, 
                    GetSearchQueryable(input),
                    "Company.Name",
                    "BLAHProcess.Name",
                    "ProcessOwner",
                    "ControlOwner",
                    "CAR"
                );

编辑2: 我将方法切换为使用T代替object,这也起作用。

public static IQueryable<T> SearchBySecurityList<T>(List<SecurityListFilter> caSecurityFilterList, IQueryable<T> qry, string companySearch, string fpSearch, string poSearch, string controlOwnerSearch, string carSearch)