2

在 LINQ 中,我如何搜索表中的所有字段,我在下面为 ANYFIELD 放置了什么?

谢谢

var tblequipments = from d in db.tblEquipments.Include(t => t.User).Include(t => t.ChangeLog).Include(t => t.AssetType)
                                where d."ANYFIELD" == "VALUE" select d;
4

4 回答 4

5

你不能。您必须单独比较每个字段。比较所有字段是没有意义的,因为一个字段甚至可能与您要比较的对象的类型不同。

于 2013-07-30T16:17:18.847 回答
3

你可以,使用反射。尝试这个:

    static bool CheckAllFields<TInput, TValue>(TInput input, TValue value, bool alsoCheckProperties)
    {
        Type t = typeof(TInput);
        foreach (FieldInfo info in t.GetFields().Where(x => x.FieldType == typeof(TValue)))
        {
            if (!info.GetValue(input).Equals(value))
            {
                return false;
            }
        }
        if (alsoCheckProperties)
        {
            foreach (PropertyInfo info in t.GetProperties().Where(x => x.PropertyType == typeof(TValue)))
            {
                if (!info.GetValue(input, null).Equals(value))
                {
                    return false;
                }
            }
        }
        return true;
    }

还有你的 LINQ 查询:

var tblequipments = 来自 db.tblEquipments.Include(t => t.User).Include(t => t.ChangeLog).Include(t => t.AssetType) 中的 d
其中 CheckAllFields(d, "VALUE", true) 选择 d;

第三个参数应该是true是否要检查所有字段所有属性,以及false是否只想检查所有字段。

于 2013-07-30T17:03:50.923 回答
1

编辑:有人已经建造了这个......见这里

不是一个完整的答案,但我不同意你根本不能......

db您可以提出一个扩展方法,该方法根据您类似类型的属性动态过滤 IQueryable/IEnumerable(我猜是 IQueryable变量)。这是在 Linqpad 中掀起的一些事情。它引用了 PredicateBuilder 并且绝不是完整/完全准确的,但我在我的一些表上在 Linq-to-SQL 中对其进行了测试,并且它按描述工作。

void Main()
{
    YourDbSet.WhereAllPropertiesOfSimilarTypeAreEqual("A String")
         .Count()
         .Dump();
}

public static class EntityHelperMethods
{
    public static IQueryable<TEntity> WhereAllPropertiesOfSimilarTypeAreEqual<TEntity, TProperty>(this IQueryable<TEntity> query, TProperty value)
    {
        var param = Expression.Parameter(typeof(TEntity));

        var predicate = PredicateBuilder.True<TEntity>();

        foreach (var fieldName in GetEntityFieldsToCompareTo<TEntity, TProperty>())
        {
            var predicateToAdd = Expression.Lambda<Func<TEntity, bool>>(
                Expression.Equal(
                    Expression.PropertyOrField(param, fieldName),
                    Expression.Constant(value)), param);

            predicate = predicate.And(predicateToAdd);
        }

        return query.Where(predicate);
    }

    // TODO: You'll need to find out what fields are actually ones you would want to compare on.
    //       This might involve stripping out properties marked with [NotMapped] attributes, for
    //       for example.
    private static IEnumerable<string> GetEntityFieldsToCompareTo<TEntity, TProperty>()
    {
        Type entityType = typeof(TEntity);
        Type propertyType = typeof(TProperty);

        var fields = entityType.GetFields()
                            .Where (f => f.FieldType == propertyType)
                            .Select (f => f.Name);

        var properties = entityType.GetProperties()
                                .Where (p => p.PropertyType == propertyType)
                                .Select (p => p.Name);

        return fields.Concat(properties);
    }
}

未解决部分的有用资源:

于 2013-07-31T17:31:23.703 回答
1

如果这对某人有帮助。

首先在 Customer 类中找到与查询相同类型的所有属性:

var stringProperties = typeof(Customer).GetProperties().Where(prop =>
    prop.PropertyType == query.GetType());

然后从上下文中找到至少一个属性值等于查询的所有客户:

context.Customer.Where(customer => 
    stringProperties.Any(prop =>
        prop.GetValue(customer, null) == query));
于 2016-08-04T12:54:47.257 回答