在我的Windows Phone Mango应用程序中,我有一堆复选框,每个复选框对应一周中的某一天。我想过滤我查询的数据,选中哪个复选框。这就是我想出来的,但我觉得有更好的解决方案:
声明XAML中的复选框:
<CheckBox Content="Mon" x:Name="MonCheckbox" Checked="DayCheckbox_Tap" Unchecked="DayCheckbox_Tap"/>
<CheckBox Content="Tue" x:Name="TueCheckbox" Grid.Column="1" Checked="DayCheckbox_Tap" Unchecked="DayCheckbox_Tap" />
<CheckBox Content="Wed" x:Name="WedCheckbox" Grid.Column="2" Checked="DayCheckbox_Tap" Unchecked="DayCheckbox_Tap" />
<CheckBox Content="Thur" x:Name="ThurCheckbox" Grid.Row="1" Checked="DayCheckbox_Tap" Unchecked="DayCheckbox_Tap" />
<CheckBox Content="Fri" x:Name="FriCheckbox" Grid.Row="1" Grid.Column="1" Checked="DayCheckbox_Tap" Unchecked="DayCheckbox_Tap" />
<CheckBox Content="Sat" x:Name="SatCheckbox" Grid.Row="1" Grid.Column="2" Checked="DayCheckbox_Tap" Unchecked="DayCheckbox_Tap" />
<CheckBox Content="Sun" x:Name="SunCheckbox" Grid.Row="2" Grid.Column="0" Checked="DayCheckbox_Tap" Unchecked="DayCheckbox_Tap" />
将一天与每个复选框相关联:
public MainPage()
{
InitializeComponent();
LayoutRoot.DataContext = this;
// This is grossly imperative. Can it be done in XAML?
MonCheckbox.Tag = DayOfWeek.Monday;
TueCheckbox.Tag = DayOfWeek.Tuesday;
WedCheckbox.Tag = DayOfWeek.Wednesday;
ThurCheckbox.Tag = DayOfWeek.Thursday;
FriCheckbox.Tag = DayOfWeek.Friday;
SatCheckbox.Tag = DayOfWeek.Saturday;
SunCheckbox.Tag = DayOfWeek.Sunday;
// ...
}
维护当前所选日期的集合:
ICollection<DayOfWeek> _selectedDays = new Collection<DayOfWeek>();
private void DayCheckbox_Tap(object sender, RoutedEventArgs e)
{
CheckBox checkbox = (CheckBox)sender;
if (_selectedDays.Contains((DayOfWeek)checkbox.Tag))
{
_selectedDays.Remove((DayOfWeek)checkbox.Tag);
}
else
{
_selectedDays.Add((DayOfWeek)checkbox.Tag);
}
refreshCheckinData();
}
当我去刷新显示给用户的数据时,问题出现了:
private void refreshCheckinData()
{
Checkins.Clear();
Checkins.AddAll(from checkin in checkinData.Items
where _selectedDays.Contains(checkin.DateTime.DayOfWeek)
select checkin);
}
public static class ExtensionMethods
{
public static void AddAll<T>(this ICollection<T> dest, IEnumerable<T> source)
{
if (dest == null)
{
throw new ArgumentNullException("dest");
}
foreach (T t in source)
{
dest.Add(t);
}
}
}
当代码尝试在source
中迭代AddAll()
时,会发生以下异常:
Method 'Boolean Contains(System.DayOfWeek)' has no supported translation to SQL." System.Exception {System.NotSupportedException}
我该如何解决这个问题?为什么Contains
需要SQL翻译?是否有更好的方法来处理这一切,使用更多的声明性XAML和更少命令性的代码隐藏?
更新:我尝试将查询更改为:
where _selectedDays.Any(day => day == checkin.DateTime.DayOfWeek)
现在我收到以下错误:
"Local sequence cannot be used in LINQ to SQL implementations of query operators except the Contains operator." System.Exception {System.NotSupportedException}
_selectedDays
在内存中定义。为什么需要将其翻译成SQL?
答案 0 :(得分:0)
如果我理解正确,那么你想把所有选定的日子添加到你的'Chekings'中,为什么你不尝试这个代码,我认为这将解决你现在的问题,并回答我必须考虑的其他问题他们有点做一些研究。 :)
foreach(var day in _selectedDays)
{
Checkins.AddAll(from checkin in checkinData.Items
where checkin.DateTime.DayOfWeek == day
select checkin);
}
必须测试这个,我不知道它是否有效或是否有效。
from checkin in checkinData.Items
join sdays in _selectedDays on checkin.DateTime.DayOfWeek == sdays
select checkin
答案 1 :(得分:0)
您的原始查询已结束。我认为ICollection上的Contains()方法正在妨碍SQL转换器 - 我需要仔细检查代码才能确定。
您可以通过将代码更改为强制选择Enumerable.Contains()扩展方法来解决此问题:
private void refreshCheckinData()
{
Checkins.Clear();
Checkins.AddAll(from checkin in checkinData.Items
where _selectedDays.AsEnumerable().Contains(checkin.DateTime.DayOfWeek)
select checkin);
}
Enumerable.Contains(T)扩展方法将转换为数据库中的IN子句。
生成的查询将是这样的: SELECT [t0]。[Key],[t0]。[Day] FROM [Stuff] AS [t0] 在哪里[t0]。[日] IN(@ p0,@ p1)