Save the result of LINQ query to list - c#

I'm trying to create handler to save the result of LINQ query to list and that what i reached to
public static List<string> Get()
{
LesamisContainer LC = new LesamisContainer();
List<string> list = (from pb in LC.PayBills
join c in LC.Customers on pb.CustomerId equals c.Id
join d in LC.Departments on pb.DepartmentId equals d.Id
select new { pb.Id, c.FullName, d.Name, pb.Discount, pb.TotalAmount, pb.Details, pb.Date, pb.CustomerId, pb.DepartmentId } into x
select x).Tolist();
return list;
}
but i got this exception
http://i60.tinypic.com/2lxu2o.png
Cannnot convert type 'System.Collections.Generic.List' to 'System.Collections.Generic.List'

You're creating an anonymous type with
select new { pb.Id, c.FullName, d.Name, pb.Discount, pb.TotalAmount, pb.Details, pb.Date, pb.CustomerId, pb.DepartmentId } into x
The select x just returns this type. To get a List<string> you would need to return on of the properties from this instead, eg: select x.FullName
That would be a pretty odd way of doing things though, and probably not what you really intend. I assume you don't actually want a List<string>.
In which case, since you're returning the result from the method it should be declared and not anonymous:
public class PayBillModel
{
public int Id {get;set;}
...
}
then
select new PayBillModel() { pb.Id, c.FullName, d.Name, pb.Discount, pb.TotalAmount, pb.Details, pb.Date, pb.CustomerId, pb.DepartmentId }
This way, you end up with a List<PayBillModel>.

You're getting multiple types. Try changing the List type to object instead of string
List<object> list = (from pb in LC.PayBills
join c in LC.Customers on pb.CustomerId equals c.Id
join d in LC.Departments on pb.DepartmentId equals d.Id
select new { pb.Id, c.FullName, d.Name, pb.Discount, pb.TotalAmount, pb.Details, pb.Date, pb.CustomerId, pb.DepartmentId } into x
select x).Tolist();
You can then browse through the list by:
foreach (object item in list)
{
if (item is pb.Id)
{
//do something
}
//or
//if (item.GetType() == typeof(PayBills)) { }
}

Related

Return List from Query

I'm trying to return a list from a join query and having difficulty with the errors..
here is my code:
public IList<UniStock.Domain.Tables.Inventory> SelectInventoryListByColourSizeGroup(string styleColour, string sizeGroup)
{
var db = new UniStockContext();
IQueryable<Domain.Tables.Inventory> q = (from c in db.Inventories
join o in db.SizeGroupSizes
on c.Size.Trim() equals o.Description.Trim()
where (c.SytleColour == styleColour)
&& (o.SizeGroup.Description == sizeGroup)
select new
{
c
});
return q;
}
Error I'm seeing now is:
Cannot implicitly convert type 'System.Linq.IQueryable' to System.Linq.IQueryable'. An explicit conversion exists (are you missing a cast?)`
The problem is, as the error says, you cannot return an anonymous type when your method is expecting a specific type. By using the new {} syntax you are creating an anonymous type. Simply remove new {}
public IList<UniStock.Domain.Tables.Inventory> SelectInventoryListByColourSizeGroup(string styleColour, string sizeGroup)
{
var db = new UniStockContext();
IQueryable<Domain.Tables.Inventory> q = (from c in db.Inventories
join o in db.SizeGroupSizes
on c.Size.Trim() equals o.Description.Trim()
where (c.SytleColour == styleColour)
&& (o.SizeGroup.Description == sizeGroup)
select c);
return q.ToList();
}
This part of your LINQ expression
select new { c } ;
Will give you a list of annonymous type objects. Your method signature says it should return an IList<Inventory>. Since you are not returning the expected type, you are getting this compile time error.
You select should be just c which is an alias for db.Inventories ( with the filter though)
var q = from c in db.Inventories
join o in db.SizeGroupSizes
on c.Size.Trim() equals o.Description.Trim()
where (c.SytleColour == styleColour)
&& (o.SizeGroup.Description == sizeGroup)
select c;
return q.ToList();
The variable q will be IQueryable<Inventory> and when you call the ToList() it will execute the LINQ expression and will get a List<Inventory> and you are returning that, which is matching with your method signature (IList<Signature>)
You are projecting into a new AnonymousType by doing this:
select new { c }
What you probably want is to select the object itself like this:
select c
Then you will want to append a .ToList() to the end to execute the query and populate the list.

C# MVC API URL string value remove case sensitive

I have C# MVC API URL localhost/api/APIValues?Name=Nick. All working but only issue is when I typed Name=nick it won't display result. because my database table name field store Nick. Also my Database table name field has some data example Nick, ANN, tristan, Abbott,BUD. How do I remove string(Name) case sensitive MVC API values?
Example, how do I setup both way work localhost/api/APIValues?Name=Nick and localhost/api/APIValues?Name=nick.
This is my C# code.
public IEnumerable<NameDTO> Get(string Name = "")
{
var nameList = (from o in db.People.AsEnumerable()
where o.name == Name
join s in db.Employee on
o.empID equals s.empID
select new
{
s.empID,
o.Id
}).ToList();
}
My finally out put should work both name "Nick or nick"
localhost/api/APIValues?Name=Nick
localhost/api/APIValues?Name=nick
You can use Equals with StringComparison:
public IEnumerable<NameDTO> Get(string Name = "")
{
var nameList = (from o in db.People.AsEnumerable()
where o.name.Equals(Name, StringComparison.OrdinalIgnoreCase)
join s in db.Employee on
o.empID equals s.empID
select new
{
s.empID,
o.Id
}).ToList();
}
Try this, I think it may help you:
// Use if you want same records with name you provide
public List<NameDTO> Get(string Name = "")
{
var nameList = (from o in db.People.AsEnumerable()
where o.name.Trim().ToLower() == Name.Trim().ToLower()
join s in db.Employee on
o.empID equals s.empID
select new NameDTO()
{
EmpId = s.empID,
Id = o.Id
}).ToList();
}
//use this if you want similar records from database
public IEnumerable<NameDTO> Get(string Name = "")
{
var nameList = (from o in db.People.AsEnumerable()
where o.name.Trim().ToLower().Contains(Name.Trim().ToLower())
join s in db.Employee on
o.empID equals s.empID
select new NameDTO()
{
EmpId = s.empID,
Id = o.Id
}).ToList();
}
}
Made it as simple as it can get. Whenever my query's don't work in a single line it's my preference to break it down into several components. Feel happy to write a one liner though.
var nameList= db.People.AsEnumerable();
People people = new People();
foreach (var x in nameList)
{
var result = x.name.ToLower() == Name.ToLower();
if (result)
{
people = x;
}
}
var Employee = db.Employee.FirstOrDefault(e => e.EmpId == people.EmpId);
NameDTO nameDTO = new NameDTO()
{
EmpId = Employee.EmpId,
Id = People.Id
};
SQL is not case sensitive. And as long as yo're using a library that converts your code to SQL (such as EF) this shouldn't be an issue.
var nameList = (from o in db.People
where o.name == Name
join s in db.Employee on
o.empID equals s.empID
select new
{
s.empID,
o.Id
}).ToList();
The problem is that you're using AsEnumerable() which actually executes the query and then compares the objects in memory instead of comparing in DB. Watch it in the SQL Profiler and you will see the difference.

LINQ - 'The type of one of the expressions in the join clause is incorrect. Type inference failed in the call to 'GroupJoin'.'

I have this query wit a group join:
foreach (var item in someList)
{
var result = (from t1 in someContext.Table1
join t2 in someContext.Table2 on new { t1.SomeID, item.SomeName} equals new {t2.SomeID, t2.SomeName} into j1
...
}
I would like to know if it is possible to have a group join as above?
new { t1.SomeID, item.SomeName} equals new {t2.SomeID, t2.SomeName}
item.SomeName comes from the list i am iterating through.
If not, how would i change the statement to get the desired results?
The types of the properties used with the equals expression must match. So for example is Table1.SomeID is Int32 and Table2.SomeID is Nullable<Int32>, then they don't match.
EDIT
foreach (var item in someList)
{
var someName = item.SomeName;
var result = (from t1 in someContext.Table1
join t2 in someContext.Table2 on
new { t1.SomeID, SomeName = someName}
equals new { t2.SomeID, t2.SomeName} into j1
...
}
Also check item.SomeName is same type as t2.SomeName
In this case you must be sure that the properties and type of the two new anonymous objects are the same. I usually give specific name of properties.
Ex.:
var result = from t1 in someContext.Table1
join t2 in someContext.Table2 on
new { SomeID = t1.SomeID, SomeName = someName} equals
new { SomeID = t2.SomeID, SomeName = t2.SomeName} into j1

LINQ and the KeyValuePairs

I'm trying to count items in a group. So I have this LINQ to Entities query:
var qry2 = from c in qry
group c by c.Content.DownloadType into grouped
select new KeyValuePair(grouped.Key,grouped.Count());
But it doesn't work because LINQ to Entities only accepts parameter initializers or parameterless constructors. So I created a simple class to envelop the KeyValuePair type:
public class ValueCount
{
public string Key { get; set; }
public int Value { get; set; }
public KeyValuePair<string, int> ToKeyValuePair()
{
return new KeyValuePair<string, int>(this.Key, this.Value);
}
}
And changed the query to:
var qry2 = from c in qry
group c by c.Content.DownloadType into grouped
select new ValueCount
{
Key = grouped.Key,
Value = grouped.Count()
}.ToKeyValuePair();
But still doesn't work. It says that it doesn't recognizes the method ToKeyValuePair()
How can I collect KeyValuePairs from a LINQ to Entities query?
You have to call your method once you have the results back from the db and you can do that by forcing the query using ToList() and then doing a select to call your method on each item.
(from c in qry
group c by c.Content.DownloadType into grouped
select new ValueCount
{
Key = grouped.Key,
Value = grouped.Count()
}).ToList().Select(x=>x.ToKeyValuePair());
Like Eric rightly says in the comments you can get rid of your custom class and do something like
(from c in qry
group c by c.Content.DownloadType into grouped
select new
{
Key = grouped.Key,
Value = grouped.Count()
}).ToList().Select(x=>new KeyValuePair<string, int>(x.Key, x.Value));
Try adding AsEnumerable() to isolate your code from EF's:
var qry2 = from c in qry
group c by c.Content.DownloadType into grouped
select new ValueCount
{
Key = grouped.Key,
Value = grouped.Count()
}.AsEnumerable() // This "cuts off" your method from the Entity Framework,
.Select(vc => vc.ToKeyValuePair()); // letting you nicely complete the conversion in memory

How should I write this Linq to Entity query?

I'm new to Linq to Entity stuff, so I don't know if what I'm doing is the best approach.
When I do a query like this it compiles, but throws an error that it doesn't recognize the method GetItemSummaries. Looking it up, this seems to be because it doesn't like a custom method inside the query.
return (from c in _entity.Category
from i in c.Items
orderby c.Id, i.Id descending
select new CategoryDto
{
Id = c.Id,
Name = c.Name,
Items = GetItemSummaries(c)
}).ToList();
private IEnumerable<ItemSummary> GetItemSummaries(CategoryDto c)
{
return (from i in c.Items
select new ItemSummary
{
// Assignment stuff
}).ToList();
}
How would I combine this into a single query since I can't call a custom method?
I tried just replacing the method call with the actual query, but then that complains that ItemSummary isn't recognized instead of complaining that the method name isn't recognized. Is there any way to do this? (Or a better way?)
You should be able to do the following:
return (
from c in _entity.Category
orderby c.Id descending
select new CategoryDto
{
Id = c.Id,
Name = c.Name,
Items = (
from i in c.Items
order by i.Id descending
select new ItemSummary
{
// Assignment stuff
}
)
}).ToList();
It's just a matter of making sure that ItemSummary is public so that it's visible to the query.
If it's just a Dto though, you could use an anon type, eg:
from i in c.Items
order by i.Id descending
select new
{
Id = i.Id,
Name = i.Name
}
This creates a type with the 'Id' and 'Name' properties. All depends what your consuming code needs :)
Try making the GetItemSummaries method an extension method on the Category class
private static IEnumerable<ItemSummary> GetItemSummaries(this Category c)
and then call it with
select new Category
{
Id = c.Id,
Name = c.Name,
Items = c.GetItemSummaries()
}).ToList();
Marc

Categories