Datatable linq select query - linq

I m trying to select a column's value from a datatable based on conditions.
var results = from DataRow myRow in dtCallBack.AsEnumerable()
where myRow.Field<DateTime>(1) == startDateTime
&& myRow.Field<int>(0) == callBackID
select myRow.Field<int>(3);
My datatable contains 4 columns ID,Date1,Date2,IntVal
I want to convert the variable results to int. (I want to return the column 4 IntVal)

var results = (from DataRow myRow in dtCallBack.AsEnumerable
where myRow.Field<DateTime>(1) == startDateTime
&& myRow.Field<int>(0) == callBackID
select myRow.Field<int>(3)).SingleOrDefault();

Well you've currently got an IEnumerable<int> by the looks of it. So which of those results do you want? What do you want to happen if there aren't any results?
If you're confident there's only a single result, you can use:
var result = results.Single();
If you want the first result or 0 if there aren't any, you could use
var result = results.FirstOrDefault();
If you want the first result and an exception if there aren't any, you could use
var result = results.First();
Basically there are lots of options, and you'll need to clarify your requirements before we can really give you a more concrete answer.

Related

Get X records from complex LINQ query

How can I get 10 records from complex LINQ query?
I tried to put .Skip(X).Take(10), but it doesn't work, depending on where I'm trying to take 10 it returns the full set of objects or nothing.
Setting .Skip(X).Take(10) at the end of the query doesn't what I'm looking for because of slow performance.
This is my query:
List<ReportReturn> report =
from var1 in context.Table1
join var2 in context.Table2
on var1.AccountID equals var2.AccountID
join var3 in context.Table3
on var1.AccountID equals var3.AccountID into all
where
var1.SubAccountID == intSubAccountID &&
// ...... and more conditions
let actual = var1.Total.GetValueOrDefault(0)
let Unique = var2.CountUnique
let Total = var2.Count
// ........ and more helper values
orderby var1.Date descending
from final in all.DefaultIfEmpty()
select new ReportReturn {
// ........................some property assigments
};
just writing
.Skip(X).Take(10)
will give you output in IEnumerable<T> type but yours is List<T> type.
So you should use
.Skip(X).Take(10).ToList()
in your case.

How to query and calculate dates in the where clause of a LINQ statement?

I am having trouble with the following piece of code. Before I paste it, Let me give a bit of history on what should happen.
I have a model containing 2 fields of interest at the moment, which is the name of the order the customer placed, and the date at which he/she placed it. A pre-calculated date will be used to query the dateplaced field (and should only query the dates , and not the time). The query counts the amount of duplicates that occur in the MondayOrder field, and groups them together. Now , when I exclude the where clause which should query the dates, the query runs great. However, The goal of this query is to count the amount of orders for the following week based on the date the order has been placed.
List<string> returnlist = new List<string>();
DateTime dt = getNextWeekMondaysDate().Date;
switch (day)
{
case DayOfWeek.Monday:
{
var CountOrders =
from x in Data.EntityDB.Orders
group x by x.MondayOrder into m
let count = m.Count()
select new
{
MondayOrderItem = m.Key, Amount = count
};
foreach (var item in CountOrders)
{
returnlist.Add(item.MondayOrderItem + " : " +
item.Amount);
}
}
break;
The getNextWeekMondaysDate() method has an overload which I can use, where if I supply it a date, it will get the following Monday's date from the parameter given. The problem is though, LINQ does not accept queries such as the following:
var CountOrders =
from x in Data.EntityDB.Orders
where getNextWeekMondaysDate(x.DatePlaced.Value).Date == dt
group x by x.MondayOrder into m
let count = m.Count()
select new { MondayOrderItem = m.Key, Amount = count };
This is exactly what I must achieve. Is there any workaround for this situation?
UPDATE
Here is the exception I get when I try the 2nd query.
LINQ to Entities does not recognize the method 'System.DateTime getNextWeekMondaysDate(System.DateTime)' method, and this method cannot be translated into a store expression.
You cannot do this directly, as user-defined method calls cannot be translated to SQL by the EF query provider. The provider recognizes a limited set of .NET methods that can be translated to SQL and also a number of canonical functions as well. Anything that cannot be expressed using these methods only is off-limits unless you write your own query provider (which is only theoretically an option).
As a practical workaround, you can calculate an appropriate range for x.DatePlaced.Value in code before the query and then use specific DateTime values on the where clause.
As an intellectual exercise, note that this method is recognized by the query provider and can be used as part of the expression. So this abomination should work too:
var CountOrders =
from x in Data.EntityDB.Orders
where EntityFunctions.AddDays(
x.DatePlaced.Date.Value,
(9 - DateAndTime.DatePart(DateInterval.WeekDay, x.DatePlaced.Value)) % 7)
.Date == dt
group x by x.MondayOrder into m
let count = m.Count()
select new { MondayOrderItem = m.Key, Amount = count };
Linq to Entities doesn't know how to convert arbitrary C# methods into SQL - it's not possible in general.
So, you have to work with the methods it does understand.
In this case, you could do something like this:
DateTime weekBegin = CalculateWeekBegin( dt );
DateTime weekEnd = CalculateWeekEnd( dt );
var CountOrders =
from x in Data.EntityDB.Orders
where x.DatePlaced.Value >= weekBegin && x.DatePlaced.Value < weekEnd
group x by x.MondayOrder into m
let count = m.Count()
select new { MondayOrderItem = m.Key, Amount = count });

How to write LINQ IN clause query which will work as LIKE operator as well?

How we can write a LINQ query for following select sql query:
string brandid="1,2,3"
string bodystyleid="1,2,3"
-------------------
-----------------
select * from car
where brandid in (brandid)
and bodystyleid in (brandid)
----------------------
-------------------
My specific requirement is that if brandid or bodystyleid is blank(if user does not select
any checkbox of a particular search option) query should return all record for that particular where condition.
Please guide me.
Thanks,
Paul
In order to fulfil your requirement about returning all items if none are specified, you need to check for the lists being empty.
var brands = brandid.Split(',').Select(x => Int32.Parse(x));
var styles = bodystyleid.Split(',').Select(x => Int32.Parse(x));
var result = from c in car
where (!brands.Any() || brands.Contains(c.brandid))
&& (!styles.Any() || styles.Contains(c.bodystyleid))
select c;
(similar to sgmoore's solution, but includes the check for no brand/style specified)
I've not actually checked how this gets converted back to SQL - it may be more efficient to use a flag to indicate whether there are any values:
var brands = ....; // As above
bool anyBrands = brands.Any()
var result = from c in car
where (!anyBrands || brands.Contains(c.brandid))
.....
Is bodystyleid meant to check brandid or bodystyleid? (I am assuming bodystyleid, however have wrote the query to match the query in the question (brandid))
As a start you could do:
var results = (from c in car
where c.brandid.Contains(brandid)
&& c.bodystyleid.Contains(brandid)
select c).ToList();
var brandids = brandid .Split(',').Select(n => int.Parse(n)).ToList();
var bodyStyleids = bodystyleid.Split(',').Select(n => int.Parse(n)).ToList();
var results =
(from c in car where
brandids.Contains(c.brandid) &&
bodyStyleids.Contains(c.bodystyleid)
select c
).ToList();
the Ids you have are as strings with comma delimiter, you need them to be collections like List of the same type as your Ids of the Car table, so if brandid column is int then brandids has to be List<long>, then you can do
var results = (
from c in cars
where brandids.Contains(c.brandid) && bodystyleid.Contains(c.bodystyleid)
select c).ToList();

right sql query

I have the following problem. In my database table I have a coloum with the name ItemDaysNext (the coloumn is an integer). The value is ever null and this is ok....
I would like use this coloumn after for a sort value...
This satement works fine:
var query = from item in items
let today = DateTime.Today
let birthday = item.ItemDate
let next = new DateTime(today.Year, birthday.Month, birthday.Day)
let next2 = next < today ? next.AddYears(1) : next
orderby (next2 - today).Days ascending
select item;
But I would like use the result from "(next2 - today).Days" into the ItemDaysNext because then I can sort after better a Listbox because I can bind the value...
This statement doesn't work and I become a compiler error message (InvalidCastException)
var query = from item in items
let today = DateTime.Today
let birthday = item.ItemDate
let next = new DateTime(today.Year, birthday.Month, birthday.Day)
let next2 = next < today ? next.AddYears(1) : next
orderby (next2 - today).Days ascending
select new { ItemDaysNext = (next2 - today).Days };
How can I make the correct Query????
Best regards for all answers.
The only way I can replicate something similar to your problem is making the column "ItemDate" nullable and putting a null value in the database. This is easily fixed by assigning birthday to something else when null eg: line 3 let birthday = item.END_DATE ?? DateTime.MaxValue

Iterating Linq result set using indexers

Let's ay I have this query:
var results = from row in db.Table select row;
How can I access this:
string name = results[0]["columnName"];
if you really want a particular index you can use the Skip() method with First().
var rowOffset = 0;
var results = (from row in db.Table
select row).Skip(rowOffset).First()["columnName"];
But unless you are using a Where clause I would really recommend using the indexer. The indexer is pretty much a direct reference while the LINQ statement would be using the objects iterator.
Also don't forget you can do much more advanced stuff with LINQ.
var rowOffset = 0;
var pageLength = 10;
var results = (from row in db.Table
let colValue = row["columnname"]
where colValue != null
select colValue.ToString()
).Skip(rowOffset)
.Take(pageLength)
.ToArray();
var commaString = string.Join(", ", results);
If you specifically just want the zeroth element, you can use results.First()
results is a IEnumerable list of Rows. So you can get it with a simple foreach.
foreach(var row in results)
{
string name = row["columnName"];
}
(from row in db.Table select row).First().columnName

Resources