C# LINQ DataTime List - c#

Have a some problem with converting to List
public List<DateTime> findDateBetween(DateTime start,DateTime end)
{
var query = from entry in sd.gw_chemistry
where (entry.insert_datetime >=start & entry.insert_datetime<=end & a == entry.well_id & b == entry.indicator_id)
select entry.insert_datetime;
return (List<DateTime>)query;
}`
Error:
System.InvalidCastException: Unable to cast object of type "System.Data.Objects.ObjectQuery1[System.Nullable1[System.DateTime]]" to type "System.Collections.Generic.List`1[System.DateTime]".

There are a number of problems with your code.
Your query is selecting elements of type DateTime? (or Nullable<DateTime>). You will need to decide what you want to do if a date is null. Exclude it from the results? Return a default value? If you can be sure it will never be null, you can select entry.insert_datetime.Value.
Your query does not return a list, you will have to convert it to a list using ToList().
For the conditional AND operator (&&) it appears you are using &.
You are using variables a and b that do not seem to be defined anywhere (unless they are member variables).
So assuming that a and b are member variables, and an insert_datetime is never null you can do:
return sd.gw_chemistry
.Where(e =>
e.insert_datetime >= start && e.insert_datetime <= end &&
a == entry.well_id && b == entry.indicator_id)
.Select(e => e.insert_datetime.Value)
.ToList();

As the error is trying to tell you, that isn't a List<T>, and you can't cast it to a type that it isn't.
You can create a List<T> from your query by calling .ToList().

public List<DateTime> findDateBetween(DateTime start,DateTime end)
{var query = from entry in sd.gw_chemistry
where (entry.insert_datetime >=start & entry.insert_datetime<=end & a == entry.well_id & b == entry.indicator_id)
select entry.insert_datetime;
return query.ToList();}

Nothing serious here. You just need to call ToList() on your query. However I do see the usage of & instead of && as a serious problem.
Correct code should look like:
public List<DateTime> findDateBetween(DateTime start,DateTime end)
{
var query =
from entry in sd.gw_chemistry
where (entry.insert_datetime >=start &&
entry.insert_datetime<=end &&
a == entry.well_id &&
b == entry.indicator_id)
select entry.insert_datetime.Value;
return query.ToList();
}`

Related

LINQ Where clause with four &&

I'm trying to create an LINQ Query with 4 arguments in the Where clause. It's a Windows 8 App project and I'm using an SQLite Database. (SQLite implementation )
Here's the code snippet:
public List<FinancialListBoxExpenseItem> retrieveExpenseItems(int month, int year, bool isPaid, StaticResources.FrequencyEnum frequencyEnum)
{
List<FinancialListBoxExpenseItem> tmpList = null;
connection.RunInTransaction(() =>
{
var items = from s in connection.Table<FinancialListBoxExpenseItem>()
where (s.expenseDateNextPayment.Month == month)
&& (s.expenseDateNextPayment.Year == year)
&& (s.expensePaidForCurrentPeriod == isPaid)
&& (s.expenseFrequencyTypeEnum == frequencyEnum)
select s;
tmpList = items.ToList<FinancialListBoxExpenseItem>();
});
return tmpList;
}
It throws a NotSupportedAction: Member access failed to compile expression Exception
I have no idea what does this mean and how i'm supposed to fix it.
Edit: it works without the where clause therefore the error must be related to this where clause part of the code
Probably .Month is not supported by your LINQ provider. You'll have to work around that, possibly by creating specialized columns for the month and the year.
This is how i solved the problem:
public List<FinancialListBoxExpenseItem> retrieveExpenseItems(int month, int year, bool isPaid, StaticResources.FrequencyEnum frequencyEnum)
{
List<FinancialListBoxExpenseItem> tmpList = new List<FinancialListBoxExpenseItem>();
connection.RunInTransaction(() =>
{
var items = from s in connection.Table<FinancialListBoxExpenseItem>()
let convertedDate = (DateTime)s.expenseDateNextPayment
where (convertedDate.Month == month)
&& (convertedDate.Year == year)
&& (s.expensePaidForCurrentPeriod == isPaid)
&& (s.expenseFrequencyTypeEnum == frequencyEnum)
select s;
tmpList = items.ToList();
});
return tmpList;
}
In my App I was getting a NotSupportedException when running a LINQ query, and the details of the exception showed
Member access failed to compile expression
As this thread let me know, the issued seemed to be caused by a DateTime variable that was being referenced in the query. Outside of finding a StackOverflow thread like this one to point you in the right direction, I'm not sure how anyone is supposed to figure that out on their own, but for me, changing the way I was writing the query fixed the problem.
This syntax was throwing the "NotSupportedException":*
IEnumerable<Foo> foos = connection.Table<Foo>().Where(foo => foo.Timestamp.Year == year);
Switching to this syntax worked just fine:
IEnumerable<Foo> foos = connection.Table<Foo>().Where(
delegate(Foo foo)
{
return (foo.Timestamp.Year == year);
});

LINQ OR operator not giving result

I have written a LINQ query with or condition in it, but its not working, it seem I am doing something wrong.
I am passing a string value and on it, I want to get my result.
var userDetails = context.tbl_members.Where
(
d => d.Mobile == value
||
d.MemberId == Int32.Parse(value)
).SingleOrDefault();
its not working if someone put a mobile no, but if work with memberID
if I split the query keep only mobile no its running fine.
var userDetails = context.tbl_members.Where(d => d.Mobile == value ).SingleOrDefault();
Please check what I did wrong with or condition
Regards
Moksha
var userDetails = context.tbl_members
.Where(d => d.Mobile == value ||
d.MemberId == Int32.Parse(value))
.SingleOrDefault();
It looks like you are using Linq to Entities or Linq to Sql. Int32.Parse() is not supported in that context - just do the number conversion before your query:
int numValue = Int32.Parse(value);
var userDetails = context.tbl_members
.Where(d => d.Mobile == value || d.MemberId == numValue)
.SingleOrDefault();
thanks for your help brokenGlass,
the error was in converting from string to int, as I was passing string of 10 digits, it was not getting converted into int
Value was either too large or too small for an Int32.
thanks

How can i use DateTime.AddXXXX functions in a Linq-to-Entities query?

I am trying to use AddMonths in a query
List<Entities.Subscriber> items = (from s in context.Subscribers
where s.Validated == false && s.ValidationEmailSent == true && s.SubscriptionDateTime < DateTime.Now.AddMonths(-1)
select s).ToList();
But I recieve an error :
LINQ to Entities does not recognize the method 'System.DateTime
AddMonths(Int32)' method, and this method cannot be translated into a
store expression.
Is there a way I can use this function inside my query?
The simplest fix to this is to work out the time limit once before using LINQ:
DateTime limit = DateTime.Now.AddMonths(-1);
List<Entities.Subscriber> items = (from s in context.Subscribers
where s.Validated == false && s.ValidationEmailSent == true &&
s.SubscriptionDateTime < limit)
select s).ToList();
Or more readably IMO:
var items = context.Subscribers
.Where(s => !s.Validated &&
s.ValidationEmailSent &&
s.SubscriptionDateTime < limit)
.ToList();
There's no benefit in using a query expression here, and explicit comparisons with true and false are ugly IMO (unless your properties are of type Nullable<bool> of course).
Jon Skeet has already provided a simple fix, but if you want the DateTime.Now.AddMonths bit to run on the database, try the EntityFunctions.AddMonths method.
This is a more general approach that is especially useful when you cannot replicate the expression cheaply or correctly on the client.
You can change your code to:
DateTime oneMonth = DateTime.Now.AddMonths(-1)
List<Entities.Subscriber> items = (from s in context.Subscribers
where s.Validated == false && s.ValidationEmailSent == true && s.SubscriptionDateTime < oneMonth
select s).ToList();
You have to do this because AddMonth is a .NET function that can't be translated into SQL by Linq to Entities. Perform the calculation in your code and then use the resulting datetime will work.

c# linq returns duplicate data

I have a this linq query:
var fling = (from b in flowering.FlowerViews
where ((!string.IsNullOrEmpty(flow_name)) && b.FLOWER_NAME == flow_name) || flow_name==""
where ((!string.IsNullOrEmpty(color_name)) && b.COLOR_NAME == color_name) || color_name == ""
where ((!string.IsNullOrEmpty(size)) && b.FLOWER_SIZE == size) || size==""
where ((low_price!=0) && low_price<= b.FLOWER_PRICE) || low_price==0
where ((high_price!=0) && high_price >= b.FLOWER_PRICE) || high_price==0
orderby b.COLOR_NAME
select new { b.FLOWER_NAME, b.COLOR_NAME, b.FLOWER_SIZE, b.FLOWER_PRICE, b.CHAR_DESC});
my where clauses work for me but when I run a for each loop over the returned values there is duplicate data because b.CHAR_DESC has 3 values to it where all the other return data only have one. I am wondering if there is a way to get the 3 values assigned to b.CHAR_DESC into a structure that does not cause duplicate b.Flower_name's to show up
Based on this post you should be able to call Distinct() for the anonymous type
var list = fling.Distinct().ToList();
And the compiler will take care of GetHashCode() and Equals() for the anonymous type based on attribute values.
Add .Distinct() at the end of your select clause, after the final parenthesis.

Multiple WHERE's in same LINQ 2 SQL Method

I have the below LINQ Method I am trying to create. The issue seems to be the Second WHERE clause. I am getting this error -->
Cannot implicitly convert type 'System.Collections.Generic.IEnumerable<MatrixReloaded.Data.CMO.tblWorkerHistory>' to 'bool'
I also had && there vs WHERE but I was getting a similar error. I don't NEED anything from tblWorkerHistories except the EndDate stuff.
There is a Many To Many relationship between the 2 tables with EnrollmentID being a FK on both.
public static DataTable GetCurrentWorkersByEnrollmentID(int enrollmentID)
{
using (var context = CmoDataContext.Create())
{
context.Log = Console.Out;
var currentWorkers = from enrollment in context.tblCMOEnrollments
where enrollment.EnrollmentID == enrollmentID
where enrollment.tblWorkerHistories.Where(a => a.EndDate == null || a.EndDate > DateTime.Now)
select
new
{
enrollment.CMONurseID,
enrollment.CMOSocialWorkerID,
SupportWorkerName = enrollment.tblSupportWorker.FirstName + " " + enrollment.tblSupportWorker.LastName,
SupportWorkerPhone = enrollment.tblSupportWorker.Phone
};
return currentWorkers.CopyLinqToDataTable();
}
}
This is the problem:
where enrollment.tblWorkerHistories.Where(/* stuff */)
Where returns a sequence... whereas you need something that will return a Boolean value. What are you trying to do with that embedded Where clause?
As Marc says, it could be that you just need an Any call instead of Where... but if you could explain what you're trying to do, that would make it a lot easier to help you. Note that Any does return a Boolean value, instead of a sequence.
EDIT: Okay, so in SQL you'd use a join, but you don't need an explicit join here because LINQ is implicitly doing that for you, right? If you're trying to find enrollments where any of the histories match the date, and you don't care about the histories themselves, then Any is indeed what you want:
var currentWorkers = from enrollment in context.tblCMOEnrollments
where enrollment.EnrollmentID == enrollmentID
where enrollment.tblWorkerHistories.Any
(a => a.EndDate == null || a.EndDate > DateTime.Now)
select ...
I suspect you mean .Any instead of .Where in the sub-query; the outermost .Where (i.e. the second where) expects a predicate expression, but yours is currently a selector - try:
where enrollment.tblWorkerHistories.Any(
a => a.EndDate == null || a.EndDate > DateTime.Now)

Categories

Resources