We have a data bound control that is populated with a list of banks.
I can figure out how to Read, Insert and Delete real accounts.
On the form, however, our client needs a way to select a "None" option (some customers use cash).
I cannot insert a "None" entry into the banks data table because of how the data tables are linked to other data tables.
I attempted to insert a "None" record before returning the DataContext so that this option would always appear at the top of the list, but there doesn't appear to be any way to get the data into the collection.
public System.Data.Linq.Table<bank> Banks
{
get
{
return this.GetTable<bank>();
}
}
I was able to insert a fake record into an IQueryable list:
internal IQueryable<bank> GetBankInfo(bool insertBlank = false)
{
var list = (from item in banks
orderby item.bank_name
select item).ToList();
if (insertBlank)
{
var item = new bank()
{
bank_name = String.Empty,
contact_name = String.Empty,
contact_phone_num = String.Empty,
routing_num = "None",
source = String.Empty,
fact_routing_num = String.Empty,
note_id = (int?)null,
};
list.Insert(0, item);
}
return (IQueryable<bank>)list;
}
But, I can't use this because it throws a TargetInvocationException:
Unable to cast object of type 'System.Collections.Generic.List1[Billing.DataDB.bank]' to type 'System.Linq.IQueryable1[Billing.DataDB.bank]'.
How do I insert a blank record for the DataContext display?
I do not want the blank record in the database.
You can fix this two ways:
First, change the return type of the method to IEnumerable<T>...
internal IEnumerable<bank> GetBankInfo(bool insertBlank = false)
...and leave out the cast in the return statement. It'll be redundant, as List<T> implements IEnumerable<T>
return list;
Based on what you mentioned in your question, this should work.
Second way:
If you're doing something else with that list/queryable/whatever, such that you really need it to really be IQueryable<T>, that's even easier. Leave the function return type as it was:
internal IQueryable<bank> GetBankInfo(bool insertBlank = false)
And return this:
return list.AsQueryable();
Here's the problem:
I was able to insert a fake record into an IQueryable list:
Actually, you weren't. You enumerated the results of an IQueryable into a new List<T> instance: That's what happened in your ToList() call. It's not a cast, it creates a new collection object. Then you inserted a fake record into the List<T>.
The thing you were casting to IQueryable<bank> wasn't the IQueryable<bank> that you started with; it was a completely different object which contained all the items that were enumerated by the IQueryable<bank>.
The purpose of IQueryable is so the actual query can be executed remotely, as with Entity Framework for example. However, once you materialize the query in the ToList() call, the remote ship has sailed the barn out of the station. Since IQueryable<T> inherits from IEnumerable<T>, I'd tend to use the latter for a general "reference to sequence of things" type. Any method that takes IEnumerable<T> for a parameter will happily consume an IQueryable<T> instead.
Related
This code snippet returns me an error,
public List<auto> autoSelect()
{
return autoSelect(DateTime.Today);
}
public List<auto> autoSelect(DateTime date)
{
var onderhoudAuto = (from onderhoud in db.onderhouds
where onderhoud.uitvoerdatum != DateTime.Today
select onderhoud)
.FirstOrDefault();
List<string> autos = (from auto in db.autos
where auto.autoId.Equals(onderhoudAuto)
select auto)
.FirstOrDefault();
return autos;
}
I tried convert the var to a list with .ToList(); although this doesn't work. Does anyone have any suggestions?
I tried convert the var to a list
No, you do not. var is not actually a data type - it is resolved by the compiler. A tooltip should show you the real type.
Your problem is different:
Looking at your code, we can see:
The method autoSelect signature states that the return type is List<auto>
public List<auto> autoSelect(DateTime date)
The variable autos type is List<string>
List<string> autos = [...etc...]
return autos;
You return autos, but it is not possible to return a List<string> when a List<auto> is expected.
So it has nothing to do with var - it is simply you selecting as single property and returning a list of strings, but that is not the type the method is supposed to return.
If you use FirstOrDefault() after your linq query, you are saying you want the first element (or the default -usually null- for the datatype if none matches) in the LINQ query, not a list of elements.
If you want a list of elements, use ToList() on the linq query, not try to convert a single entity to a list.
If you, for some reason, want a list of a single entity, then create a list (with new List<type>()) and then add your entity (of the same type as your list) to the list.
So I have a DataTable object, which I want to populate based on a table from my database. Currently, I do the following:
public Task<IEnumerable<DataDTO>> Loadreferences(int Id)
{
IEnumerable <DataDTO> DTOList = _context.Data.Where(p => p.Id == Id).Select(p => new DataDTO
{
Id = p.Id,
Children = p.Children
});
return Task.FromResult(DTOList);
}
The original table in my database is called Data and contains a lot of other stuff that I have left out for this question. However, the point in constructing this datatable object is basically to reduce the payload towards the server (as it leaves out some of the columns and transform others)
I can successfully populate my DTO, but I have a problem populating the children. Naturally this is because, the list of children is pointing to objects of type Data, and I try to use it in type DataDTO.
Therefore, I get an error stating that I can't convert a list of Data objects to a list of DataDTO objects.
Do I really need a loop to fix this for me, or can I do it with a simple query?
So it turned out, that there was a relatively easy fix to this:
foreach (DataDTO data in datas)
{
data.Children = datas.Where(p => p.ParentId == data.Id).ToList();
}
By doing the following, I didn't have to recursively add new objects in my select statement or do some sort of stored procedure.
The loop simply checks if any items in the list has the current looped item as parentId, whereafter it appends to the children property.
I am using a variable var for getting the result from my database and I want to compare it with my enum value to do some processes. But I am facing the problem var cant compare with the enum value.I have tried to convert both of the variable to String but still cant make it. Any idea of doing so?
//Fetch the value from database
var resultActivateQR = from value in db.QrCodes
where value.Code == qrCode
select value.Status;
//Want to compare the value
if (resultActivateQR.Equals((int)Status.New))
{
return true;
}
else
{
return false;
}
//My Enum In other class
public enum Status
{
New = 0,
Activated = 1,
Void = 2,
}
Your variable resultActivateQR would be an IEnumerable collection object returned from your LINQ statement. You would need to use a LINQ method like .Single() or .First() to get the Status of the one record that matched your qrCode (assuming there should always just be one record return from the database from the LINQ statement).
So your code could look something like this (this is more concise but essentially does what it seems like you needed):
var resultActivateQR = db.QrCodes.Where(x => x.Code == qrCode).Single();
//Want to compare the value
return resultActivateQR.Status == (int)Status.New;
This will bring back the single object the represents the database record that matches your QR Code and then compares that objects status to your enum Status.New and will return true or false from the comparison.
Writing a LINQ query, as you did, creates just queryable object, which does not contain any data, just query itself. It is called deferred exectuion, meaning that data is fetched when it is needed.
So one way is to call method such as ToList() or ToArray().
From your question I guess you expect one record to be fetched or you want to get one record, which requires calling First() method or FirstOrDefault(), which would also materialise data.
Second matter is the type of Value column, but I guess it's an int, so you can easily compare with your enum. Otherwise, you should cast your enum to appropriate datatype in order to successfully compare it with value in column.
I am working on one project and I have a question regarding the converting type. I want to create simple search for my project, but it can't return result with this message :
Error 1 Cannot implicitly convert type 'System.Collections.Generic.List' to 'EmployeeDataAccess.TimeWorkMonthly'
public TimeWorkMonthly Get(int id)
{
using (EmployeeDbEntities Entities = new EmployeeDbEntities())
{
List<TimeWorkMonthly> persons = new List<TimeWorkMonthly>();
var result = Entities.TimeWorkMonthlies
.Where(e => e.KartNo == id)
.Select(e => e)
.ToList();
return result.ToList();
}
}
The return type of your method is TimeWorkMonthlies but inside the method body return List<TimeWorkMonthlies>
You should either
change your method return type to IEnumerable<TimeWorkMonthlies>
(You could use List<TimeWorkMonthlies> but using an interface to abstract a collection type is better for many reasons)
Use FirstOrDefault, First, SingleOrDefault or Single extension methods of IEnumerable if you aim to return only one element and you do not care about anything except for the first element
Which of those methods is better depends on your data and search criteria - i.e. whether you expect this ID to be unique or not.
From your semantics it looks like you're doing a sort of repository like ID lookup, so my guess would be solution 2) and using Single or SingleOrDefault
The last choice is how you want your program to behave if nothing is found by ID
If you want an exception, use Single
If you want a null use SingleOrDefault
In Summary, all you have to do is change your last line of code to
return result.Single();
(And ofcourse, you don't need a call to ToList() just before that)
Your method signature indicates you just want to return a single object. But you're returning a List of objects. Using .ToList() is not appropriate when you just want to return one object. There are four appropriate extension methods:
First - will return the first item from the collection and throw an exception if the collection is empty.
FirstOrDefault - will return the first item in the collection, or the default of the type if the collection is empty.
Single - if there is one item in the collection, it will return it. If there are no items in the collection an exception is thrown. If there are multiple items in the collection, an exception is thrown.
SingleOrDefault - if there is one item in the collection it will return it. If there are no items in the collection it will return the default value for the type. If there are multiple items in the collection it will thrown an exception.
Since you're searching by ID, you probably don't ever to expect to match two or more elements. So that rules out First and FirstOrDefault. You should use Single or SingleOrDefault depending on what you want the behavior to be if there is no item found that has the matching ID.
public TimeWorkMonthly Get(int id)
{
using (EmployeeDbEntities Entities = new EmployeeDbEntities())
{
var result = Entities.TimeWorkMonthlies.Where(e => e.KartNo == id).Single();
return result;
}
}
Note I eliminated the persons variable because you never did anything with it. And your usage of the .Select extension method was superflous since you just selected the same object already being iterated over. Select is for when you want to transform the object.
The problem is your qry only . If you want to convert it with Tolist() function you have to change your qry
like this
public TimeWorkMonthly Get(int id)
{
using (EmployeeDbEntities Entities = new EmployeeDbEntities())
{
var result = from x in Entities.TimeWorkMonthlies
Where x.KartNo == id
Select x;
return result.ToList();
}
}
You can now convert it to list by tolist() and use it according to your need.
I am trying to do something like a SQL 'in', which I understand to be more or less equivalent to 'contains' in LINQ.
This is the query I've come up with after reading through several other similar questions and this...
http://blogs.msdn.com/b/alexj/archive/2009/03/26/tip-8-writing-where-in-style-queries-using-linq-to-entities.aspx
public ActionResult recentbookings(string recent_bookings)
{
List<booking> bookings = db.bookings.Where(s => recent_bookings.Contains("36525")).ToList();
return PartialView("_recentbookings", bookings);
}
This query returns every record in the table.
I want and expect the query to return one record matching the id I'm passing in.
The 'recent_bookings' value is coming from localstorage through a javascript call...
var url = '#Url.Action("recentbookings", "booking")';
url += "?recent_bookings="+ localStorage['recent_bookings'];
$("#ajaxresult").load(url);
There happens to be only one item in local storage, which is '36525', which matches the hardcoded 'Contains("36525")' in my query.
I believe there's a simple problem with my query logic as I don't really understand it, compared with the SQL in.
Once I get this sorted out, I'll go on to parsing out multiple values from the incoming string.
public ActionResult recentbookings(string recent_bookings)
{
var recent_bookings_array = new[] { int.Parse(recent_bookings) };
booking[] bookings = db.bookings.Where(s =>
recent_bookings_array.Contains(s.Id)).ToArray();
return PartialView("_recentbookings", bookings);
}
You were using .Contains incorrectly. You are right, it is like an IN clause, but the object you invoke .Contains on should be like the IN (36525) part of your SQL query. The above query is basically saying "Give me all of the bookings where the booking ID is in this array of recent booking id's."
Why is your result returning all booking records?
...because the Where clause argument is a Func<T, bool>. Meaning, the result of the lambda expression must be either true or false. The expression in your question, s => recent_bookings.Contains("36525") will always return true, since the string "36525" is contained within your recent_bookings variable. Since it is always true, all of your rows get returned. You never checked anything against your data, only your local variables.
On another note, don't call .ToList on your result unless you need to add / remove items to / from it before returning the view. .ToArray is much faster, but returns an immutable collection.