LINQ中的动态查询

时间:2012-07-20 15:26:02

标签: c# linq linq-to-sql

我在网络表单中有四个按钮,其目的是分别加载第一个,上一个,下一个和最后一个记录。 他们通过获取表单中加载的当前ID并按要求执行操作。我正在使用Linq to SQL。 下面是我用于NEXT记录的代码,如果我想按ID加载下一条记录,它的功能正常。

var dx = new DataModelDataContext();
List<Dog> dogList = dx.Dogs.AsEnumerable().ToList();

try
{
    return
        dogList.SkipWhile(x => x.Id != dogId).Skip(1).FirstOrDefault().Id.ToString(
            CultureInfo.InvariantCulture);
}
catch
{
    return null;
}

我再说一遍,对于上一个场景,这段代码运行正常。

场景发生了变化,我现在必须根据前面提到的按钮检索记录 一个下拉列表,其中包含表单的属性(FirstName,LastName,Gender等...)因此它不再是一个具有定位意图的函数 通过身份证明的下一条记录。

我正在考虑创建一个LoadNextRecord(searchParameter,TextboxValue),以便根据属性找到下一条记录 从下拉列表中指定。

但是,是否可以动态指定我想要比较数据的属性?

示例:x =&gt; x。[searchParameter]!= textboxvalue

我知道这可以使用Dynamic sql ...但是我想知道是否可以使用LINQ。

4 个答案:

答案 0 :(得分:4)

如果您使用Dynamic Linq,则可以。通过downloading the sample here,您可以在此路径的zip中找到一个文件:LinqSamples\DynamicQuery\DynamicQuery\dynamic.cs。通过添加该文件并正确使用,您可以使用一些IQueryable扩展方法,以便以字符串格式表达方式。在拉链中有关于如何使用的示例。使用这个解决方案,你会被所谓的“魔术字符串”所困扰,但不是那么“神奇”,因为linq表达式是在幕后编译的。

答案 1 :(得分:1)

您可以在基类上放置一个公开searchParameter()成员的接口。

var searchValue = dogId;
return 
    dogList.SkipWhile(x => x.searchParameter() != searchValue).Skip(1).FirstOrDefault().Id.ToString(CultureInfo.InvariantCulture);

答案 2 :(得分:1)

你可以使用反射

        var dx = new DataModelDataContext();
        List<Dog> dogList = dx.Dogs.AsEnumerable().ToList();

        string PropetyToCheck = "MyProperty";

        PropertyInfo property = typeof(Dog).GetProperty(PropetyToCheck);

        try
        {
            return
                dogList.SkipWhile(x => property.GetValue(x, null) != dogId).Skip(1).FirstOrDefault().Id.ToString(
                    CultureInfo.InvariantCulture);
        }

答案 3 :(得分:0)

编辑**对不起,误读了问题,反思会更好。

编辑***

实际上,不,你可以将组合框绑定到一组具有谓词属性的对象,然后是onchange / button事件(无论你用什么去下一条记录)你可以从组合框中取出对象,并使用它linq方法中的谓词。

它确实意味着要为要跳过的每个属性维护一组对象,但如果你想要另外添加另一个属性,你还是要做一些工作。

Dictionary<string, Predicate<YourType>> filters = new ...
filters.Add("YourProp", x => x.yourProp == "blah blah");

Combobox box = new ...
box.ValueMember = "Value";
box.DispayMember = "Key";
box.DataSource = filters;

var pred = box.SelectedValue as Predicate<YourType>;
if (pred != null)
{
    GoToNextRecord(pred);
}

然后在linq方法......

dogs...Skip(pred)...;