我有一个自定义方法,用于获取与jqGrid一起用于搜索的选择列表的字符串。
所需的字符串格式为":All;value1:text1;value2:text2"
我目前有以下方法以可重用的方式实现此目的:
public static string jqGridFilterSelectList<TSource>(this IQueryable<TSource> source,Expression<Func<TSource, string>> selector)
{
return string.Join(";", source.Select(selector).Distinct().ToArray());
}
这可行,但需要调用如下:
string filterSelectList = service.GetAllUsers().jqGridFilterSelectList(x=>x.User + ":" + x.User);
我不太乐意使用像x=>x.User + ":" + x.User
这样的选择器。我想把它转换成2个这样的重载(伪代码!!)
// case where we want the value and text of the select list to be the same
public static string jqGridFilterSelectList<TSource>(this IQueryable<TSource> source,Expression<Func<TSource, string>> selector)
{
return string.Join(";", source.Select(selector + ":" + selector).Distinct().ToArray());
//obviously this won't work, but is it possible in some other way while executing it on the database still? Also is it possible to insist the selector only contains 1 column.
}
//case where we want different text and value
public static string jqGridFilterSelectList<TSource>(this IQueryable<TSource> source,Expression<Func<TSource, string>> textSelector,Expression<Func<TSource, string>> valueSelector)
{
return string.Join(";", source.Select(valueSelector + ":" + textSelector).Distinct().ToArray());
}
我想我可以使用动态linq实现这一点,但我很想知道这是否可行。
答案 0 :(得分:1)
如果我理解正确,你几乎已经写好了:
public static string jqGridFilterSelectList<TSource>(
this IQueryable<TSource> source,
Expression<Func<TSource, string>> selector
)
{
var compiled = selector.Compile();
return string.Join(";",
source.Select(x => compiled(x) + ":" + compiled(x))
.Distinct().ToArray()
);
}
//case where we want different text and value
public static string jqGridFilterSelectList<TSource>(
this IQueryable<TSource> source,
Expression<Func<TSource, string>> textSelector,
Expression<Func<TSource, string>> valueSelector
)
{
return string.Join(";",
source.Select(x => valueSelector.Compile()(x) + ":" + textSelector.Compile()(x))
.Distinct().ToArray()
);
}
你只需要调用你的选择器函数来获取值。 如果我误解了你的问题,请告诉我。
对于第二个问题,是否可以坚持选择器只包含1列,简单答案是否 - 选择器几乎可以是任何有效Func
的{{1}并且返回TSource
并且没有办法限制内部可以做的事情(除非你想检查提供的表达式树,但它会比结果更复杂,当然)。
编辑:好的,这是某种SQL LINQ提供程序,实体框架?所以让我们尝试一下不同的方式。我不知道它是否可行,但让我们先尝试获取数据并连接对象:
string
其他 public static string jqGridFilterSelectList<TSource>(
this IQueryable<TSource> source,
Expression<Func<TSource, string>> selector
)
{
var compiled = selector.Compile();
return string.Join(";",
source.Distinct().AsEnumerable()
.Select(x => compiled(x) + ":" + compiled(x))
.ToArray()
);
}
//case where we want different text and value
public static string jqGridFilterSelectList<TSource>(
this IQueryable<TSource> source,
Expression<Func<TSource, string>> textSelector,
Expression<Func<TSource, string>> valueSelector
)
{
return string.Join(";",
source.Distinct().AsEnumerable()
.Select(x => valueSelector.Compile()(x) + ":" + textSelector.Compile()(x))
.ToArray()
);
}
调用在数据库和进程内处理之间切换。假设您的选择器是确定性的并且没有任何副作用,您可以对已经提取的ToEnumerable
项进行操作。
答案 1 :(得分:1)
实现所需内容的另一种方法是使用searchoptions的dataUrl
和buildSelect
参数。
如果value
字符串形式为&#34;:All; value1:text1; value2:text2&#34;在真正需要之前不会建造(直到第一次搜索)。当用户单击搜索对话框时,jqGrid将从dataUrl
获取数据。服务器方法可以具有非常清晰的接口并返回List<string>
的JSON表示。在客户端,您可以定义buildSelect
事件句柄,将["text1", "text2", ...]
转换为<select>
。一切都好。使用这种方法的示例可以找到here。与示例相比,您只需在select元素中添加其他选项<option value="">All</option>
。
有时您还应该使用ajaxSelectOptions jqGrid参数来自定义获取选择列表数据的相应$.ajax
请求。
方式的优点:
buildSelect
的另一个实现中,您应该只跳过在选择列表中插入<option value="">All</option>
。