The result of a query cannot be enumerated more than once. - c#

I have a listview dialog to bind a data to that listview.
private void BindListView(string DCLookupMstr_Value, int reportCatId, string DCLookup_Value = null)
{
using (Model.OperationalAnalyticsEntities oadb = new Model.OperationalAnalyticsEntities())
{
var res = oadb.prGetDailyCensusLookup(DCLookupMstr_Value, reportCatId, DCLookup_Value);
Session["LookupValues"] = res;
lvLookup.DataSource = res.ToList();
lvLookup.DataBind();
}
}
And I put a search box(textbox) on that listview dialog. If user type any text/chars, using linq query..populate the listview again with the values which contains given chars. My code is below
protected void txtSearch_TextChanged(object sender, EventArgs e)
{
var text = txtSearch.Text;
//var list = new List<Model.prGetDailyCensusLookup_Result>();
var lookUpValue = Session["LookupValues"] as ObjectResult<Model.prGetDailyCensusLookup_Result>;
var list = lookUpValue.Where(x => x.DCLookup_Value.Contains(text));
lvLookup.DataSource = list.ToList();
lvLookup.DataBind();
}
I am getting the "result of a query cannot be enumerated more than once" where ever i added .ToList(). I am not sure what did I miss.
Please Help!

In BindListView, when you do .ToList(), it enumerates the query for the first time. And what you store in the session is the query itself. When you do .ToList() again in txtSearch_TextChanged, it enumerates the query a second time, which is not supported.
You should store the result of .ToList() in the session, rather than the query:
Session["LookupValues"] = lvLookup.DataSource = res.ToList();

You value you are storing in Session is the LINQ query, not the result of the query. The second time it is used (the list.ToList()) it throws this error.
This is easily fixed by storing the result as a list in Session instead.
var res = oadb.prGetDailyCensusLookup(DCLookupMstr_Value, reportCatId, DCLookup_Value)
.ToList();
Session["LookupValues"] = res;
lvLookup.DataSource = res;
lvLookup.DataBind();

Related

Linq into the array then find values in the array and list to combobox

I would like to return the result of the LINQ query to the array, the list then look in this array for example with the letter "A". And return the list to the combobox containing all the letters "A".
My linq query:
var collectionName = (
from row in repos.GetTable<Table_Names>()
select row.Name
).Distinct().ToArray();
And I do not know now how to search the array so that it will find all of them containing the letter "A".
Ultimately, I would like to search in the array instead of sending queries to the database. That would make the list in the combobox narrow down dynamically.
I think it's better to get the filtered collection, instead for perform search after getting the collection. So I suggest you to use a Where clause like the following to get filtered items only:
string searchString ="A";
from row in repos.GetTable<Table_Names>()
where row.Name.Contains(searchString)
select row.Name;
Instead for Contains you can also try StartsWith if you want to get the collection of strings that starts with the given search text.
If you don't want to filter in the database, you can use linq to objects to further filter the collection in memory:
var filtered = collectionName.Where(item => item.Contains("A")).ToArray();
You can use SqlMethods.Like in LINQ query. Check the code below
private void comboBox1_TextChanged(object sender, EventArgs e)
{
comboBox1.DataSource = getItems(comboBox1.Text);
comboBox1.DisplayMember = "Name";
comboBox1.ValueMember = "ID";
}
public static List<ComboboxItem> getItems(string text)
{
DataClasses1DataContext context = new DataClasses1DataContext();
try
{
List<ComboboxItem> Ilist = new List<ComboboxItem>();
var query = from x in context.testComboBoxes where SqlMethods.Like(x.name, '%' + text +'%') select x;
foreach (var q in query)
{
ComboboxItem item = new ComboboxItem();
item.ID = q.id;
item.Name = q.name;
Ilist.Add(item);
}
return Ilist;
}
catch (Exception ex)
{
return null;
}
}
public class ComboboxItem
{
public object ID { get; set; }
public string Name { get; set; }
}

filling combo box using LINQ query (distinct)

I have a combocox the name is "cmbModel" I want to fill the database with two different values in a table.
This is what I have done:
private void Form1_Load(object sender, EventArgs e)
{
using (LINQSQLDataContext db = new LINQSQLDataContext())
{
cmbModel.DisplayMember = "szModel";
cmbModel.DataSource = db.VehEcus.ToList<VehEcu>();
}
}
this will fill my cmbModel with szModel column of my table but I want to avoid repeating , how can I use "distinct" in query to achieve my goal?
and also I want to show 2 items of my table like "modelID-szModel" in my combobox
Thanks
If you just want to show a single column anyway you could select that column and use Distinct:
cmbModel.DataSource = db.InfoProg_VehEcus.Select(x => x.szModel).Distinct();
You can apply Distinct() at any point after your query. I recommend doing it before you enumerate.
To create the custom modelID-szModel field, you can enumerate the query using AsEnumerable(), then create an anonymous type and use String.Format to concatenate your values into your new field.
using (LINQSQLDataContext c = new LINQSQLDataContext ())
{
var items = c.VehEcus.Select(t => new
{
a = t.szModel,
b = t.modelID
}).Distinct()
.AsEnumerable().Select(t => new
{
displayMember = String.Format("{0}-{1}", t.a, t.b)
});
cmbModel.DisplayMember = "displayMember";
cmbModel.DataSource = items.ToList();
}

Query to sort through highscores windows phone c#

I am having trouble with my query to display in my observable collection. I have never used linq before and I'm not sure what to do. I looked a tutorial through Microsoft at http://msdn.microsoft.com/en-us/library/vstudio/bb397906.aspx but it not provide even close what I'm trying to do. All I need help with is writing the code to search through the database ToDoItem and display highest integer value first and then go in descending order. Here is my code:
protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e)
{
var toDoItemsInDB = from ToDoItem todo in toDoDB.ToDoItems
select todo;
ToDoItems = new ObservableCollection<ToDoItem>(toDoItemsInDB);
base.OnNavigatedTo(e);
}
Just order the collection on the integer value you want to order by. Assume Score is this in the following example:
ToDoItems.OrderBy(h => h.Score);
To order a collection in descending order...
var todoItems = new List<int>();
todoItems.Add(1);
todoItems.Add(2);
todoItems.Add(3);
todoItems.Add(5);
var toDoItemsInDB = todoItems.OrderByDescending(t => t);
or, if it has an object and property...
var todoItems = new List<ToDo>();
todoItems.Add(ToDo1);
todoItems.Add(ToDo2);
todoItems.Add(ToDo3);
todoItems.Add(ToDo5);
var toDoItemsInDB = todoItems.OrderByDescending(t => t.HighScores);

Filter out results in entities C# does not contain a definition for execute

I wanted to filter out results using this command from the query, but i get this error:
Here is the code causing the error:
private void Bookings_Loaded(object sender, RoutedEventArgs e)
{
WpfApplication7.AllensCroftEntities1 allensCroftEntities1 = new WpfApplication7.AllensCroftEntities1();
// Load data into Bookings. You can modify this code as needed.
var bookingsViewSource = ((CollectionViewSource)(this.FindResource("bookingsViewSource")));
var bookingsQuery = this.GetBookingsQuery(allensCroftEntities1).Where(x => x.Date == variables.date);
bookingsViewSource.Source = bookingsQuery.Execute(MergeOption.AppendOnly);
private System.Data.Objects.ObjectQuery<Booking> GetBookingsQuery(AllensCroftEntities1 allensCroftEntities1)
{
EDIT
here it is
System.Data.Objects.ObjectQuery<WpfApplication7.Booking> bookingsQuery = allensCroftEntities1.Bookings;
// To explicitly load data, you may need to add Include methods like below:
// bookingsQuery = bookingsQuery.Include("Bookings.Client").
// For more information, please see http://go.microsoft.com/fwlink/?LinkId=157380
// Update the query to include Room.Bookings data in Bookings. You can modify this code as needed.
bookingsQuery = bookingsQuery.Include("Room.Bookings");
// Returns an ObjectQuery.
return bookingsQuery;
}
EDIT
BY THE WAY HERE IS A VIDEO OF MY PROBLEM IF IT HELPS video of problem
edit now im getting this error:
If you want to change the merging option from a query you should use
((ObjectQuery)bookingsQuery).MergeOption = MergeOption.AppendOnly;
If yoiu want the query to be executed you can call .ToList() that this will execute the query and your filters will be applied
your code should be like
var bookingsQuery = this.GetBookingsQuery(allensCroftEntities1).Where(x => x.Date == variables.date);
((ObjectQuery)bookingsQuery).MergeOption = MergeOption.AppendOnly;
bookingsViewSource.Source = bookingsQuery.ToList();
There is no Execute. The bookingsQuery will "execute" automatically as part of the data consumer iterating over the data the query defines.

The result of a query cannot be enumerated more than once

I am using the entity framework (ef) and am getting the following error:
"The result of a query cannot be enumerated more than once.".
I have a repository class which contains the ef data context. I then have a controller class (not to be confused with MVC controllers) which contains an instance of the repository. So far so good... I have a search method on the controller which is supposed to return an array of RadComboBoxItemData, which is used to populate a Telerik RadComboBox control.
public RadComboBoxItemData[] Search(int id, string searchText)
{
var query = context.Search(id, searchText);
List<RadComboBoxItemData> result = new List<RadComboBoxItemData>();
foreach (var item in query)
{
RadComboBoxItemData itemData = new RadComboBoxItemData();
itemData.Text = ""; // assign some text here..;
itemData.Value = ""; /*assign some value here..*/
result.Add(itemData);
}
return result.ToArray();
}
When I debug my code, I can get into the foreach loop, but then I get an error saying:
An exception of type
'System.InvalidOperationException'
occurred in System.Data.Entity.dll but
was not handled in user code
Additional information: The result of
a query cannot be enumerated more than
once.
My entity uses a function import of an existing stored proc.
// EF repository method calling the function imported method on the data context.
public IEnumerable<SearchItem> Search(int id, string searchText)
{
return this.entityContext.Search(id, searchText);
}
The function import Search calls a stored precedure to return a collection of SearchItem.
I have a feeling that the foreach loop can't iterate because of something with the ef.
Try explicitly enumerating the results by calling ToList().
Change
foreach (var item in query)
to
foreach (var item in query.ToList())
Try replacing this
var query = context.Search(id, searchText);
with
var query = context.Search(id, searchText).tolist();
and everything will work well.
Problematic code calling an stored procedure:
var resultSP = db.StoredProcedure(id);
if (resultSP != null)
{
var count = resultSP.Count();
var list = resultSP.Select(x=>...);
}
Fixed, store in a variable with ToList() and reuse it:
var resultSP = db.StoredProcedure(id);
if (resultSP != null)
{
var resultSP_List = resultSP.ToList();
var count = resultSP_List.Count();
var list = resultSP_List.Select(x=>...);
}
if you getting this type of error so I suggest you used to stored proc data as usual list then binding the other controls because I also get this error so I solved it like this
ex:-
repeater.DataSource = data.SPBinsReport().Tolist();
repeater.DataBind();
try like this

Categories