Linq converting implicitly to type - c#

Hi I have following method with linq statement in it.
public prO Getproject(int id)
{
var tt = (from c in db.pdi
where c.id==id
select new prO
{
name = c.p.name,
pr_id = c.p.pr_id,
re = c.p.re
});
return tt;
}
The above method returns one value of tt. However I keep getting intelicense error
(local variable) IQueryable<prO>tt
Error:
cannot implicitly convert system.linq.iqueryable to prO
Please let me know how to this error. Thanks

You are returning a collection with your query.
Since you want only one item change your query to:
public prO Getproject(int id)
{
var tt = (from c in db.pdi
where c.id==id
select new prO
{
name = c.p.name,
pr_id = c.p.pr_id,
re = c.p.re
//change here
}).FirstOrDefault();
return tt;
}
The error tells you the following: Your method has a return type of prO, but your query doe not return this type. You are nowhere defining, that you are returning excatly one item of prO. As far as the compiler is concerned, there could be 1000 items with a matching Id.
EDIT:
Based on Rawlings comments, it would be preferrable to use SingleOrDefault() instead. Both solutions are per se working, the difference however is that FirstOrDefault returns any amount of results, but takes only the first one, whereas Single or SingleOrDefault lets the query itself return exactly a single item.
Note, that if your query returns more than 1 result, FirstOrDefault displays the first result. SingleOrDefault will throw an exception.

Use return tt.FirstOrDefault();

Related

C# - Cant convert var to List

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.

Error: “Cannot implicitly convert type”

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.

Cannot implicitly convert type 'System.Linq.IQueryable<AuthenticationApp.Models.User>' to 'AuthenticationApp.Models.User'

My linq is this:
User us = from s in entities.Users
where s.Username.Equals(username)
select s;
Any idea why I am getting the above error?
Use FirstOrDefault:-
User us = (from s in entities.Users
where s.Username.Equals(username)
select s).FirstOrDefault();
Your query is returning multiple results but you are trying to store that in AuthenticationApp.Models.User which can hold just one object thus the conversion error.
Or better:-
User us = entities.Users.FirstOrDefault(x => x.Username.Equals(username));
Update:
If you are sure it will return just 1 object back, you can use SingleOrDefault too. Check differences between both here.
You are getting error because projection returns IEnumerable (IQueryable). To get User by its name you can use the following:
try
{
var user = entities.Users.SingleOrDefault(u => u.Username.Equals(username));
}
catch
{
// handle the case when there are more than
// one user with given name in DB
}

Using variables to build a LinQ query?

I don't think is possible but wanted to ask to make sure. I am currently debugging some software someone else wrote and its a bit unfinished.
One part of the software is a search function which searches by different fields in the database and the person who wrote the software wrote a great big case statement with 21 cases in it 1 for each field the user may want to search by.
Is it possible to reduce this down using a case statement within the Linq or a variable I can set with a case statement before the Linq statement?
Example of 1 of the Linq queries: (Only the Where is changing in each query)
var list = (from data in dc.MemberDetails
where data.JoinDate.ToString() == searchField
select new
{
data.MemberID,
data.FirstName,
data.Surname,
data.Street,
data.City,
data.County,
data.Postcode,
data.MembershipCategory,
data.Paid,
data.ToPay
}
).ToList();
Update / Edit:
This is what comes before the case statement:
string searchField = txt1stSearchTerm.Text;
string searchColumn = cmbFirstColumn.Text;
switch (cmbFirstColumn.SelectedIndex + 1)
{
The cases are then done by the index of the combo box which holds the list of field names.
Given that where takes a predicate, you can pass any method or function which takes MemberDetail as a parameter and returns a boolean, then migrate the switch statement inside.
private bool IsMatch(MemberDetail detail)
{
// The comparison goes here.
}
var list = (from data in dc.MemberDetails
where data => this.IsMatch(data)
select new
{
data.MemberID,
data.FirstName,
data.Surname,
data.Street,
data.City,
data.County,
data.Postcode,
data.MembershipCategory,
data.Paid,
data.ToPay
}
).ToList();
Note that:
You may look for a more object-oriented way to do the comparison, rather than using a huge switch block.
An anonymous type with ten properties that you use in your select is kinda weird. Can't you return an instance of MemberDetail? Or an instance of its base class?
How are the different where statements handled, are they mutually excluside or do they all limit the query somehow?
Here is how you can have one or more filters for a same query and materialized after all filters have been applied.
var query = (from data in dc.MemberDetails
select ....);
if (!String.IsNullOrEmpty(searchField))
query = query.Where(pr => pr.JoinDate.ToString() == searchField);
if (!String.IsNullOrEmpty(otherField))
query = query.Where(....);
return query.ToList();

Unknown "System.Object" to "string" or XML

I am using Entity Framework with
var result = db.Database.SqlQuery<object>(dynamicSQLString);
var res = result.ToList();
Where dynamicSQLString can be anything... can return a "count()", can be a select with a list of rows.... etc.... there is no way to match it with a known class type. So I thought of using "object".
I would like to know if this is the way to go, and if it is, how can I "convert" the result into a "string"...... ?
Is this even possible?
Update #1
var t1 = result.GetType(); //System.Data.Entity.Internal.InternalSqlQuery
var res = result.ToList();
var first = res.First();
var t2 = first.GetType(); // System.Object
If I do a count on "res" I get the expected number of rows, but I do NOT see a way to get the "property names" of this object/dynamic row, neither it's values.
Update #2
I've found a "similar" example, but in there the person knows exactly the parameters/types the select will return.
http://www.codeproject.com/Articles/206416/Use-dynamic-type-in-Entity-Framework-4-1-SqlQuery
you can't convert the result into string unless your SQL query
(in this case dynamicSQLString)
return premitive primitive such as
"select name from customers" that return a string result for each row in database
You could use the dynamic type instead:
http://msdn.microsoft.com/en-us/library/dd264736.aspx
However you will need to do some casting on it before you can put it into a list.

Categories