Search for null field in Linq query - c#

Using T-SQL in SQL Server Management Studio this query returns exactly what I am expecting
SELECT * FROM ZipCodeTerritory WHERE ZipCode IS NULL and StateCode = 'WA'
However... the following Linq query returns no results. I've checked the connection string and I have verified I'm connecting to the database. Using a value for the cleanZip variable will return a list. Using a null value, however, never returns anything.
string cleanZip = (item.ToUpper().Equals("NULL") ? null : item.Trim());
var zipCodes = (from z in db.ZipCodeTerritory
where z.ZipCode.Equals(cleanZip) && z.StateCode.Equals(searchState)
select z).ToList();

Changed the query to the following and it is working now.
var zipCodes = (from z in db.ZipCodeTerritory
where (cleanZip == null ? z.ZipCode.Equals(null) : z.ZipCode.Equals(cleanZip)) && z.StateCode.Equals(searchState)
select z).ToList();

Related

Get formatted date in string format in LINQ to Entities

I am using the following LINQ to Entities code for getting data from a database table named Stocks:
IEnumerable<DrugInfoViewModel> Info = from a in db.Stocks.Where(
r => r.SiteID == SiteID
&& r.MachineID == MachineID
&& EntityFunctions.TruncateTime(r.ExpiryDate) <= ExpiryDate)
select new DrugInfoViewModel()
{
ItemName = a.DrugBrand.Name,
ItemBatchNo = a.BatchNo,
ItemExpiryDate = (a.ExpiryDate == null ? null :
Convert.ToDateTime(a.ExpiryDate).ToString("MM/dd/yyyy")),
Quantity = (int?)a.Qty
};
Here, ItemExpiryDate is a string field and a.ExpiryDate is a nullable datetime field in the table. When I run this code I am getting this error:
LINQ to Entities does not recognize the method 'System.String ToString(System.String)' method, and this method cannot be translated into a store expression.
This same line of code works properly in another page. Why is this happening?
Just add ToList() or ToArray() method after Where(). This will fetch filtered objects to your memory and you will be able to call ToString(). Please, make sure that you call ToList() after filtering to avoid fetching all of the records from the table.
IEnumerable<DrugInfoViewModel> Info = from a in db.Stocks.Where(
r => r.SiteID == SiteID
&& r.MachineID == MachineID
&& EntityFunctions.TruncateTime(r.ExpiryDate) <= ExpiryDate)
.ToList()
select new DrugInfoViewModel()
{
ItemName = a.DrugBrand.Name,
ItemBatchNo = a.BatchNo,
ItemExpiryDate = (a.ExpiryDate == null ? null :
Convert.ToDateTime(a.ExpiryDate).ToString("MM/dd/yyyy")),
Quantity = (int?)a.Qty
};
This happens because the LINQ expression is evaluated on the server side i.e. inside SQL Server and there the function ToString() is not available.
As suggested in the comments already: Get a DateTime, format on the client side.

GetBytes method cannot be translated into a store expression

I am using LINQ to select a list based on a particular condition. The attribute value is stored in byte array, which is later encrypted while storing in the database table. I want to using this attribute in my SELECT LINQ query now, but it is throwing the following exception when I try to:
LINQ to Entities does not recognize the method 'Byte[] GetBytes(System.String)' method, and this method cannot be translated into a store expression.
This is the code that I using:
var result = (from history in context.Histories
where history.ID == Id &
(history.Salary != null || history.Salary != Encoding.ASCII.GetBytes("0"))
select (DateTime?)history.Date).Max();
return result;
I want to select the date from the history table, of those id's whose salary is either not equal to null or 0. How can I change this?
Just get the bytes first :
var bytes = Encoding.ASCII.GetBytes("0");
var result = (from history in context.Histories
where history.ID == Id &
(history.Salary != null || history.Salary != bytes)
select (DateTime?)history.Date).Max();
return result;
Change your code to:
var bytes = Encoding.ASCII.GetBytes("0");
var result = (from history in context.Histories
where history.ID == Id &
(history.Salary != null || history.Salary != bytes)
select (DateTime?)history.Date).Max();
return result;
LINQ can't evaluate your GetBytes when it translates your query to SQL

LINQ and check for !=null

Never used LINQ within C# before until 30 mins ago and am struggling to find an answer to my query online (probably due to my lack of understanding).
I have a simple query
var variableName = from a in tableName.AsEnumerable()
where a.column1 == item1
&& a.column2 == item2
&& a.column3 != null
select a;
The SQL column is defined as an int, null.
When the code encounters a record that is null on the database for column3, the following error is generated "the value for column3 in table <tableName> is DBNull".
Instead of checking for != null, i guess i should be using something else, but have attempted checking for DBNull.Value but the compiler states "Operation != cannot be applied to operands of type int and system.DBNull".
Any ideas?
This looks like a typed dataset, which : yeuch - stop using those, but I digress.
As such, accessing a.column3 will always raise an exception if that value is DBNull. You would need to use the typed-dataset pattern:
&& !c.Iscolumn3Null()
tableName.AsEnumerable() makes the query in-memory, so all table rows are downloaded from DB and the conditions are checked on application.
Try that:
var variableName = from a in tableName
where a.column1 == item1
&& a.column2 == item2
&& a.column3 != null
select a;
It should be translated into an SQL query and download only necessary rows.
Try this..
var variableName = from a in tableName.AsEnumerable()
where a.column1 == item1
&& a.column2 == item2
&& a.column3 != dbnull.value
select a;
try
var variableName = from a in tableName.AsEnumerable()
where a.column1 == item1
&& a.column2 == item2
&& !DBNull.Value.Equals(a.column3)
select a;
edit apparently I need to read up on typed data sets :) and why I should never use them

EF Query: How to convert zero-count subquery to null

Using EF 4.5, I want to convert a zero-count sub-query (relatedDrivers) to null in the following statement:
var query = from car in context.tblCar
let relatedDrivers = (from driver in context.tblDriver
where driver.CarId == car.CarId
select driver)
select new
{
CarId = car.CarId,
Drivers = relatedDrivers.Count() == 0 ? null : relatedDrivers
};
But I get the 'NotSupportedException' stating that it is impossible create a null constant value of type 'System.Linq.IQueryable`1' !
I wonder why this is so hard for Entity Framework to translate this query to T-SQL. Examining a sub-query and returning NULL if the result count is zero doesn't seem to be that much complicated.
Any solution and explanation is highly appreciated.
The solution is IQueriable.DefaultIfEmpty(). So the query will be changed to:
var query = from car in context.tblCar
let relatedDrivers = (from driver in context.tblDriver
where driver.CarId == car.CarId
select driver).DefaultIfEmpty()
select new
{
CarId = car.CarId,
Drivers = relatedDrivers
};

How to get SQL query into LINQ form in C# code

How can I convert the following SQL queries into LINQ query form in C#, .NET 3.5 code:
1)
select COUNT(distinct Skill_Name)
from Table1
where Department = 'ABC' and Skill_Name is not null
2)
select distinct location, country from Customer where Customer_Code ='1001';
I suspect you want:
var query = from entry in dbContext.Table1
where entry.Department == "ABC" && entry.SkillName != null
select entry.SkillName;
var count = query.Distinct().Count();
Or using extension method syntax, in one go:
var count = dbContext.Table1
.Where(entry => entry.Department == "ABC" &&
entry.SkillName != null)
.Select(entry => entry.SkillName)
.Distinct()
.Count();
As shown by mesiesta, you can combine query expressions with calls not supported within query expressions, but I tend to assign the query expression to an intermediate variable... I personally find it clearer, but use whichever you (and your team) prefer.
Something like this
int count = (from p in Table1
where p.Department == "ABC" && p.Skill_Name != null
select p.Skill_Name).Distinct().Count();
For second query you can use this
var query= (from p in Customer
where p.Customer_Code=="1001"
select new { Location=p.location ,Country=p.country}).Distinct();
you can use linqpad to convert to linq and lambda expressions

Categories

Resources