Method 'Boolean Contains(System.DayOfWeek)' has no supported translation to SQL - linq-to-sql

In my Windows Phone Mango app, I have a bunch of checkboxes, each corresponding to a day of the week. I want to filter the data I query by which checkboxes are checked. Here's what I've come up with, but I feel like there's a better solution:
Declare the checkboxes in 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" />
Associate a day with each checkbox:
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;
// ...
}
Maintain a collection of the currently selected days:
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();
}
The problem comes when I go to refresh the data that's displayed to the user:
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);
}
}
}
When the code tries to iterate over source in AddAll(), the following exception occurs:
Method 'Boolean Contains(System.DayOfWeek)' has no supported translation to SQL." System.Exception {System.NotSupportedException}
How can I get around this? Why does Contains require a SQL translation? Is there a better approach to this whole thing, using more declarative XAML and less imperative code-behind?
Update: I tried changing the query to:
where _selectedDays.Any(day => day == checkin.DateTime.DayOfWeek)
now I get the following error:
"Local sequence cannot be used in LINQ to SQL implementations of query operators except the Contains operator." System.Exception {System.NotSupportedException}
_selectedDays is defined in memory. why does it need to be translated to SQL?

Your original query is close. I think the Contains() method on ICollection is getting in the way of the SQL translator -- I would need to double check the code to be sure.
You can work around this by forcing selection of the Enumerable.Contains() extension method by changing your code to this:
private void refreshCheckinData()
{
Checkins.Clear();
Checkins.AddAll(from checkin in checkinData.Items
where _selectedDays.AsEnumerable().Contains(checkin.DateTime.DayOfWeek)
select checkin);
}
Enumerable.Contains(T) extension method will translate into an IN clause in the database.
The resulting query will be something like this:
SELECT [t0].[Key], [t0].[Day]
FROM [Stuff] AS [t0]
WHERE [t0].[Day] IN (#p0, #p1)

If i understand it correctly then you wanna add all selected days to your 'Chekings' so why don't you try this code, i think this will solve your problem for now and to answer the other questions i have to think about them a bit a do some research. :)
foreach(var day in _selectedDays)
{
Checkins.AddAll(from checkin in checkinData.Items
where checkin.DateTime.DayOfWeek == day
select checkin);
}
Would have to test this one i don't know if it works or not or if it is even valid.
from checkin in checkinData.Items
join sdays in _selectedDays on checkin.DateTime.DayOfWeek == sdays
select checkin

Related

How to show datatable from mysql to asp.net

Here is the code i make, and plese help me to create function to show datatable when i click the button.
protected void Button1_Click(object sender, EventArgs e)
{
str = "Select count(name) as total, sum(case when status = 'DONE' then 1 else 0 end) as total_done, sum(case when status = 'PROGRESS' then 1 else 0 end) as total_progress from person where name = 'RAKA'";
cmd = new MySqlCommand(str, con);
MySqlDataReader reader = cmd.ExecuteReader();
while (reader.Read())
{
tot1.Text = reader["total"].ToString();
done1.Text = reader["total_done"].ToString();
prgs1.Text = reader["total_progress"].ToString();
tb1. = reader["total"].ToString();
}
}
Ok, in most cases to display some data, you don't need a loop.
However, you do want to use say a gridview (which is table anyway - just with nice fancy and easy to use asp.net stuff wrapped around it).
So, say you have this markup:
<div style="padding:35px;width:40%">
<asp:GridView ID="GridView1" runat="server" CssClass="table">
</asp:GridView>
</div>
So, now in the code behind, to load this grid (table) up, you can use this code:
protected void Button1_Click(object sender, EventArgs e)
{
string str =
"Select count(name) as total, sum(case when status = 'DONE' then 1 else 0 end) as total_done, "
+ "sum(case when status = 'PROGRESS' then 1 else 0 end) as total_progress from person where name = 'RAKA'";
DataTable rstData = new DataTable();
using (MySqlConnection con = new MySqlConnection(Properties.Settings.Default.TEST4))
{
using (MySqlCommand cmd = new MySqlCommand(str, con))
{
con.Open();
rstData.Load(cmd.ExecuteReader());
}
}
// now send data table to grid view
GridView1.DataSource = rstData;
GridView1.DataBind();
}
So, you want using System.Data - that is the basic table and rows and operations. That part (ado.net) is the basic objects you need. You then adopt your "provider".
for exmaple, I don't have MySQL installed, but I using sql server. So ONLY the provider part need be change.
So with above markup, I can fill out the gridview like this:
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
LoadGrid();
}
void LoadGrid()
{
using (SqlConnection conn = new SqlConnection(Properties.Settings.Default.TEST4))
{
string strSQL = "SELECT * FROM Fighers";
using (SqlCommand cmdSQL = new SqlCommand(strSQL, conn))
{
conn.Open();
DataTable rstData = new DataTable();
rstData.Load(cmdSQL.ExecuteReader());
GridView1.DataSource = rstData;
GridView1.DataBind();
}
}
}
And I now see/get this on the page:
but, often I will use the wizards to create the grid, and then REMOVE the data source on teh page, and use my above code. (I use the wizrard to setup the grid view, since I am lazy.
But, lets tweak up the gird. I don't want "ID", and the path name to the image, lets drop in a iamge control.
So, my markup now becomes this:
<div style="padding:35px;width:50%">
<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False"
DataKeyNames="ID" CssClass="table" >
<Columns>
<asp:BoundField DataField="Fighter" HeaderText="Fighter" />
<asp:BoundField DataField="Engine" HeaderText="Engine" />
<asp:BoundField DataField="Thrust" HeaderText="Thrust" />
<asp:BoundField DataField="Description" HeaderText="Description" />
<asp:TemplateField HeaderText="View">
<ItemTemplate>
<asp:Image ID="Image1" runat="server" width="150px"
ImageUrl = '<%# Eval("ImagePath") %>' /> />
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="View">
<ItemTemplate>
<asp:Button ID="cmdView" runat="server" Text="View" CssClass="btn" />
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
And the code can be as before.
So, I added a image control to the grid, and a button.
So now we see/get this:
Again, note how we did NOT use a loop. But we fill out a table, and then send that table to the grid view.
And the above idea quite much applies to any kind of repeating data.
So, you can use repeater, a Gridview, listview, datalist view etc. You can feed such controls "repeating" data, and thus no need for some loop to try and fill out controls. (and if you need repeating data, then how do you add more controls to the page - that's too hard. So, use the data aware controls, and they will render that type of data for you, especially for repeating types of data.

Blazor Form with Dynamic Number of Questions

I'm trying to create a testing application that pulls question/data answer from a database. The tests each have a different number of questions (some 10, some 15, some 12) that all need to be displayed with their answer choices (some multiple choice with 4 or 5 answers, some true/false). I want to utilize the Blazor form structure to allow access to input validation, but it seems that the form Model has to have a static number of members (i.e. only 10 test questions). I tried binding the form to a class with a List of length n, where n is the number of test questions (and consequently, the number of answers), but that only recorded the first answer despite setting the #bind-Value to separate indexes of the List.
Is it at all possible to utilize dynamic data structures in Blazor Form Modeling or should I look at doing something different?
Edit: For the sake of clarity, let me dump my code here. I'm using the Radzen form libraries, which can be found here. All relevant data structures and initializers can be found below, as well.
My question lies in where I bind the RadioButtonList to the answer model: #bind-Value=#selectedAnswers.testAnswers[curr.Key]. Can I do this? I'm currently getting an 'index out of bounds' error in that statement.
Some code:
<RadzenTemplateForm TItem="Answers" Data=#selectedAnswers Submit=#GradeExam>
#foreach (KeyValuePair<int, List<string>> curr in shuffledAnswers){
<RadzenCard>
<label class="col 2 font-weight-bold"><strong>#curr.Key) #allQuestions[curr.Key.ToString()].question</strong></label>
<RadzenRadioButtonList
#bind-Value=#selectedAnswers.testAnswers[curr.Key]
TValue="int" Name=#(curr.Key.ToString())
Orientation="Radzen.Orientation.Vertical"
>
<Items>
#foreach (string s in curr.Value){
<RadzenRadioButtonListItem Text=#s Value=#curr.Value.IndexOf(s) />
Console.WriteLine("radio button");
}
</Items>
</RadzenRadioButtonList>
<RadzenRequiredValidator Component=#(curr.Key.ToString()) Text="This question is required." Popup="true" />
#if(submitted){
<br/><label class="col 2 font-weight-bold"><em>#allQuestions[curr.Key.ToString()].tooltip</em></label>
}
</RadzenCard>
}
<RadzenCard>
#if(!submitted){
<RadzenButton ButtonType="Radzen.ButtonType.Submit" Text="Submit" style="background-color: royalblue;" />
}
else {
<!-- go back to course list -->
}
</RadzenCard>
</RadzenTemplateForm>
#code{
// test answer binding model
private class Answers{
List<string> Answers;
public TestAnswers(){
Answers = new List<string>();
}
}
private Answers selectedAnswers;
private Dictionary<int, List<string>> shuffledAnswers;
private Dictionary<string, Question> allQuestions;
// ^ Question class contains the question and associated answers
private void ShuffleAnswers{
// iterate through all question data
foreach(KeyValuePair<string, Question> q in allQuestions){
// generate temporary string to hold answers
List<string> temp = new List<string>();
temp.Add(q.Value.correct);
temp.Add(q.Value.wrong1);
// if multiple choice w/ 4 answers, add them too
if(q.Value.wrong2 != "N/A"){
temp.Add(q.Value.wrong2);
temp.Add(q.Value.wrong3);
}
List<string> ans = new List<string>();
shuffledAnswers.Add(int.Parse(q.Key), ans);
// move a random answer from temp to the list of shuffled answers
while(temp.Count > 0){
int index = new Random(DateTime.Now.GetHashCode()).Next(temp.Count);
shuffledAnswers[int.Parse(q.Key)].Add(temp[index]);
temp.RemoveAt(index);
}
// initialize selected answer indexes
selectedAnswers.testAnswers.Add(0);
}
}
}

change child framelayout height,width,gravity programmatically?

change child framelayout height,width,gravity programmatically?
I have linearlayout as parent and framelayout as child now I want to change height and width of framelayout programmatically
code I tried but does not effect at all
public void frame_params(FrameLayout bottomFrameLayout, int weight, int height) {
bottomFrameLayout = new FrameLayout(context);
LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(weight, height);
lp.gravity = Gravity.BOTTOM | Gravity.LEFT;
bottomFrameLayout.setLayoutParams(lp);
}
xml
<LinearLayout
android:orientation="horizontal"
android:id="#+id/relativelayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_above="#+id/hv_effect"
android:layout_below="#+id/effect_hedaer_toolbar">
<FrameLayout
android:id="#+id/FrameLayout"
android:layout_width="280dp"
android:layout_height="300dp"
android:layout_alignParentBottom="true"
android:layout_alignParentLeft="true"
android:layout_centerInParent="true"
android:layout_gravity="bottom|left">
</FrameLayout>
</Linearlayout>
I believe this line is your problem:
bottomFrameLayout = new FrameLayout(context);
In the frame_params method, you receive a FrameLayout. But, then, you instantiate a NEW one with that line. So, indeed, the FrameLayout inside the LinearLayout will continue the same way, because you are not changing it, you are creating a new FrameLayout and you're setting the parameters to it. Just try removing the aforementioned line, like this:
public void frame_params(FrameLayout bottomFrameLayout, int weight, int height) {
LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(weight, height);
lp.gravity = Gravity.BOTTOM | Gravity.LEFT;
bottomFrameLayout.setLayoutParams(lp);
}
And, then, pass the correct FrameLayout (the one with the id "FrameLayout", as specified in your xml), it should work.
Let me know if it worked, and, if it did, remember to upvote/select as the correct answer, cheers : )

A first chance exception of type 'System.ArgumentException' while creating dynamic pivot item

I am trying to create pivot item dynamically,
here the code which i used
paginationPivot.Items.Clear();
for (int i = 1; i <= pagecount; i++)
{
TextBlock textBlock = new TextBlock();
textBlock.Foreground = new SolidColorBrush(Colors.Blue);
textBlock.FontSize = 30;
textBlock.Text = (i).ToString();
Border border = new Border();
PivotItem pivotItem = new PivotItem() { Name="item"+i.ToString(), Header=textBlock, Content=border,Margin= new Thickness(0,-70,0,0), FlowDirection=System.Windows.FlowDirection.RightToLeft};
paginationPivot.Items.Add(pivotItem);
}
here the error which i got
A first chance exception of type 'System.ArgumentException' occurred in Microsoft.Phone.ni.dll
Can anybody please help me to solve this issue.
Thank you.
but i got this error while while creating pivot item
You can't set directly "Header=textBlock", just using a string hold content that you want to show.
E.g: Header="header 1".
If you want to use more complex UI, let's use HeaderTemplate:
<controls:Pivot.HeaderTemplate>
<DataTemplate>
<StackPanel Background="#666666" Margin="0">
<TextBlock FontSize="30" Foreground="Blue" Text="{Binding}"/>
</StackPanel>
</DataTemplate>
</controls:Pivot.HeaderTemplate>
And after that:
<controls:PivotItem Header="header 1">
</controls:PivotItem>

LongListSelector Load items Infinite

For my windows phone 8 app, my data provider provides 10 items per page and i have to show the results in a LongListSelector.
My first challenge is that it provides data in JSON that i parse to array, so i cannot easily add items in my longlistselector.ItemsSource. Well, will do it somehow by observableCollection.
Second challenge is when user scrolls down to 8th or 9th item i have to load page 2 and so on until it returns items less than 10.
I am done with ItemRealized event, it is called for all 10 items at load so if i load page 2 it will load all the pages before screen loading.
I have checked the TwitterSearch example msdn has but unfortunately its api is expired. Any help?
EDIT
For my test projects, item template is below.
<phone:LongListSelector.ItemTemplate>
<DataTemplate >
<ListBoxItem Margin="20">
<TextBlock FlowDirection="LeftToRight" Text="{Binding}" Margin="0,10,0,0" Foreground="#343330" FontSize="24"/>
</ListBoxItem>
</DataTemplate>
</phone:LongListSelector.ItemTemplate>
and the binding is below.
ObservableCollection<string> data = new ObservableCollection<string>();
.
.
.
IsLoading = true;
for (int i = 0; i < 10; i++)
data.Add(string.Format("item {0}", (pageNo * 10) + (i + 1)));
pageNo++;
IsLoading = false;
itemRealized event is given below
private void LongListSelector_ItemRealized(object sender, ItemRealizationEventArgs e)
{
//data.ItemCount = data.ItemCount + 1;
itemCount++;
if (itemCount < 100
&& reloadOnItem.Contains(itemCount))
{
loadData();
}
}