Why would a nullable int give this error using linq?
public void test(int? variableId)
{
var date = _dbContext.Set<MyEvent>()
.Where(x => x.Calendar.id == (variableId.HasValue ? variableId : x.Calendar.id))
.ToList();
}
variableId.HasValue is false
variableId is null
You should write it as (variableId.HasValue ? variableId.Value : x.Calendar.id)
Assuming variableId is null, then you have a very funny expression .Where(x => x.Calendar.id == x.Calendar.id) that means - all records. The problem with your code is that having your original where expression most likely cause client side filtering but not sql side filtering. It is better to rewrite it like:
var date = variableId.HasValue
?_dbContext.Set<MyEvent>().Where(x => x.Calendar.id == variableId.Value))
:_dbContext.Set<MyEvent>();
Related
In my sql database WorkDay field is in string format and in model it is nullable DayOfWeek, i.e public DayOfWeek? WorkDay { get; set; }. While Converting database WorkDay field into model WorkDay field it will generate an error like:
Could not translate expression 'Table(StaffSchedule)' into SQL and
could not treat it as a local expression.
I have also tried to create three different linq statements which are as below.
1) Retrieve Data from StaffSchedule table.
2) Apply select operation on it.
3) Apply AddRange operation on selected data.
results.AddRange(dataContext.StaffSchedules
.Where(x => !x.Excluded)
.Where(x => x.DistrictID == districtId && x.District.Active && (x.Position == positionTeacher || x.Position == positionDirector || x.Position == positionAssistant || x.Position == positionAssistantDirector))
.Select(x => new Core.StaffSchedule()
{
ID = x.ID,
Staff = x.Staff.SelectSummary(),
Position = (StaffPosition)Enum.Parse(typeof(StaffPosition), x.Position, true),
Class = refs.Class,
District = x.District.SelectSummary(),
Time = null,
Reoccurring = false,
Inherited = true,
ReoccourringStart = x.ReoccourringStart,
ReoccourringEnd = x.ReoccourringEnd,
WorkDay = x.WorkDay == null ? (DayOfWeek?)null : (DayOfWeek)Enum.Parse(typeof(DayOfWeek), x.WorkDay, true)
}));
This is the conversion code for string to nullable DayOfWeek field. Which cause an error in my case.
WorkDay = x.WorkDay == null ? (DayOfWeek?)null : (DayOfWeek)Enum.Parse(typeof(DayOfWeek), x.WorkDay, true)
I have already gone through below link.
How to solve issue "Could not translate expression ...into SQL and could not treat it as a local expression."
Try to convert dataContext.StaffSchedules to IEnumerable by calling ToList()
method before making the query like this
results.AddRange(dataContext.StaffSchedules.ToList()
.Where(x => !x.Excluded)....the rest of you query
Search for difference between IEnumerable and IQueryable for more detailed explain
You can't translate any C# code to SQL so x.WorkDay == null ? (DayOfWeek?)null : (DayOfWeek)Enum.Parse(typeof(DayOfWeek), x.WorkDay, true) won't work in Linq to Entities.
Try to select your data after the query execution by writing AsEnumerable() before Select. Don't do it at the beginning of the query because you will fetch all the data from a db table.
results.AddRange(dataContext.StaffSchedules
//everything (well almost) from this point is going to be translated into SQL
.Where(x => !x.Excluded)
.AsEnumerable() //everything from here is going to be executed after the query ends so it can be any C# code
.Select(x => new Core.StaffSchedule()
{
//now this should work
WorkDay = x.WorkDay == null ? (DayOfWeek?)null : (DayOfWeek)Enum.Parse(typeof(DayOfWeek), x.WorkDay, true)
});
I am getting the error below and I am not sure the syntax is correct for multiple criteria in the LINQ query.
My code thus far,
static class MyQuery
{
private static Func<DatabaseDataContext, IQueryable<Staff_Time_TBL>>
queryFor =
CompiledQuery.Compile((DatabaseDataContext db, DateTime dDate) =>
db.Staff_Time_TBLs.Where(a => a.Date_Data == dDate &&
a.Time_Data_1 == null && a.Time_Data_2 == null).FirstOrDefault());
}
DatabaseDataContext is the name of the LINQ to SQL class.
Staff_Time_TBL is the table to get data from.
This is the error,
Error CS0029 Cannot implicitly convert type 'System.Func
(Example3.DatabaseDataContext, System.DateTime,
Example3.Staff_Time_TBL)' to 'System.Func
(Example3.DatabaseDataContext,
System.Linq.IQueryable(Example3.Staff_Time_TBL))'
I would post all my attempts at getting this right ,but would clutter the post.
Used this as research to get to this point.
How to: Store and Reuse Queries
Compiled Queries (LINQ to Entities)
How to improve your LINQ query performance by 5 X times?
Compiled Queries in LINQ
You've defined your field as:
Func<DatabaseDataContext, IQueryable<Staff_Time_TBL>>
Which has the equivelant method signature:
public IQueryable<Staff_Time_TBL> SomeMethod(DatabaseDataContext db)
{
...
}
But look at what you're passing it:
(DatabaseDataContext db, DateTime dDate) =>
db.Staff_Time_TBLs.Where(a => a.Date_Data == dDate &&
a.Time_Data_1 == null && a.Time_Data_2 == null)
.FirstOrDefault()
With the equivelant method:
public Staff_Time_TBL SomeMethod(DatabaseDataContext db, DateTime dDate)
{
return
db.Staff_Time_TBLs
.Where(a => a.Date_Data == dDate && a.Time_Data_1 == null && a.Time_Data_2 == null)
.FirstOrDefault();
}
This has two arguments, not one. You're also executing .FirstOrDefault(), which means you're returning Staff_Time_TBL - not IQueryable<Staff_Time_TBL>
Without knowing exactly what you're trying to do, it's likely you should re-write the field as:
private static Func<DatabaseDataContext, DateTime, Staff_Time_TBL>
queryFor =
CompiledQuery.Compile((DatabaseDataContext db, DateTime dDate) =>
db.Staff_Time_TBLs.Where(a => a.Date_Data == dDate &&
a.Time_Data_1 == null && a.Time_Data_2 == null).FirstOrDefault());
I have a query like this :
result =
firstIdeaRepository.FindBy(
i => i.FirstIdeaState == FirstIdeaState && i.Date >= start && i.Date <= end)
.AsEnumerable()
.Select(j => new RptListOfCompanyBasedOnFirstIdeaState()
{
Name =
companyRepository.FindBy(i => i.UserId == j.UserId)
.FirstOrDefault()
DateOfMeeting =
calenderRepository.ConvertToPersianToShow(
meetingReposiotry.FindBy(s => s.FirstIdeaId == j.Id)
.FirstOrDefault()
.Date),
DateOfExit =
calenderRepository.ConvertToPersianToShow(j.DateOfExit.Value),
ReasonOfExit = j.ReasonOfExit,
}).ToList();
return result;
As you can see i use FirstOrDefault() and j.DateOfExit.Value and sometimes my Date doesn't have any values or sometime my other variables are null too because i use firstordefaut() like
companyRepository.FindBy(i => i.UserId == j.UserId).FirstOrDefault().
So my query throws a null exception and the result can't be created ,how can i handle this exception and for example if the .NET detects the null value ignores it by default or uses a default values for that ?
Best regards.
I would make the following changes:
result =
firstIdeaRepository.FindBy(
i => i.FirstIdeaState == FirstIdeaState && i.Date >= start && i.Date <= end)
.AsEnumerable()
.Select(j => new RptListOfCompanyBasedOnFirstIdeaState()
{
Name =
companyRepository.FindBy(i => i.UserId == j.UserId)
.FirstOrDefault()
DateOfMeeting =
callenderRepository.ConvertToPersianToShow(
meetingReposiotry.FindBy(s => s.FirstIdeaId == j.Id)
// project a new sequence first, before calling `FirstOrDefault`:
.Select(s => s.Date)
.FirstOrDefault(),
DateOfExit =
j.DateOfExit.HasValue ?
callenderRepository.ConvertToPersianToShow(j.DateOfExit.Value) :
null,
ReasonOfExit = j.ReasonOfExit,
}).ToList();
When you use FirstOrDefault, there's a possibility that you'll get null back (in the case of reference types), and so you need to plan for that in your code.
For example, when assigning DateOfMeeting, you could project the results (using .Select) before using .FirstOrDefault, so that you're not ever accessing the Date property on what could be a null value.
As for DateOfExit, I've used the conditional operator to determine whether to call the calendarRepository's method at all. This assumes that DateOfExit is nullable.
Unrelated: "Calendar" is spelled with one "l" and not two.
Since you're using a nullable date, you can try filtering by values that have date, something like:
.FindBy(s => s.FirstIdeaId == j.Id && s.Date.HasValue)
This will ensure that you don't get any records with null date.
As I mentioned in comments, other cases need to be handled on case-by-case basis. Judging by the code you've shown, maybe you can handle Name as:
Name = companyRepository.FindBy(i => i.UserId == j.UserId).FirstOrDefault() ?? "anonymous";
and so on.
Another example:
If you do want to get the record even if DateOfMeeting is null, then add a check for HasValue in subsequent part or default it to some date:
DateOfExit = j.DateOfExit.HasValue ?
callenderRepository.ConvertToPersianToShow(j.DateOfExit.Value)
: (DateTime)null, // you need to make `DateOfExit` nullable and then handle that downstream
// or (default with current date)
DateOfExit = j.DateOfExit.HasValue ?
callenderRepository.ConvertToPersianToShow(j.DateOfExit.Value)
: callenderRepository.ConvertToPersianToShow(DateTime.Now),
// or (default with empty date)
DateOfExit = j.DateOfExit.HasValue ?
callenderRepository.ConvertToPersianToShow(j.DateOfExit.Value)
: callenderRepository.ConvertToPersianToShow(new DateTime()),
Moral of the story: figure out what the default value should be in case of null and then substitute that accordingly in the query when calling FirstOrDefault().
The broadest solution would be to use the idea of an null object with the DefaultIfEmpty<T>(T DefaultValue) method in your query. An example would be:
var defaultMeeting = new Meeting() { Date = new DateTime() };
var dateOfMeeting = meetingRepository.FindBy(s => s.FirstIdeaId == j.Id)
.DefaultIfEmpty(defaultMeeting)
.FirstOrDefault()
.Date;
I've got a method which can accept an optional int? value as a number of items to Take from a collection. I want to return all items if a null value is passed. Right now I have to duplicate my query to accomplish this
if(take == null)
{
x = db.WalkingDeadEps.Where(x => x.BicyclesCouldHaveSavedLives == true).ToList()
}
else
{
x = db.WalkingDeadEps.Where(x => x.BicyclesCouldHaveSavedLives == true).Take(take).ToList()
}
Is there a simpler way? Something like this?
.Take(take != null ? take : "all")
with Linq you have the option to store your query in variables. it will not be executed until you call ToList or equivalent methods on it.
var query = db.WalkingDeadEps.Where(x => x.BicyclesCouldHaveSavedLives == true);
x = take.HasValue ? query.Take(take.Value).ToList() : query.ToList();
My project is using MVC 4 C# LINQ to SQL.
For some reason the method used to get data for one of my properties is giving a "has no supported translation to SQL" error. The method to fetch this data is nearly identical to the method of another property in the same query except the one that works grabs a string where the one that doesn't gets a decimal.
Exact error code:
Method 'System.Decimal GetModelDifficulty(System.String)' has no supported translation to SQL.
I've tried numerous variations on the below code but I always get the same error as above:
public List<ProductionSchedule> GetBaseProductionSchedule(DateTime selectedDate)
{
var spaList = (from x in db.WO010032s
join y in db.MOP1042s on x.MANUFACTUREORDER_I equals y.MANUFACTUREORDER_I into x_y
where x.STRTDATE == selectedDate && (x.MANUFACTUREORDERST_I == 2 || x.MANUFACTUREORDERST_I == 3)
from y in x_y.DefaultIfEmpty()
select new ProductionSchedule()
{
MO = x.MANUFACTUREORDER_I,
BOMNAME = x.BOMNAME_I,
SpaModel = x.ITEMNMBR,
MoldType = GetMoldType(x.ITEMNMBR.Trim()),
SerialNumber = y.SERLNMBR,
Difficulty = GetModelDifficulty(x.ITEMNMBR.Trim())
}).OrderByDescending(x => x.Difficulty).ToList();
return spaList;
}
public string GetMoldType(string model)
{
return db.SkuModelDatas.Where(x => x.Value == model).Select(x => x.MoldType).FirstOrDefault();
}
public decimal GetModelDifficulty(string model)
{
return (decimal)db.SkuModelDatas.Where(x => x.Value == model).Select(x => x.Difficulty).FirstOrDefault();
}
Well I've tweaked the code around enough times to where I've stumbled on a variation that works:
public List<ProductionSchedule> GetBaseProductionSchedule(DateTime selectedDate)
{
var spaList = (from x in db.WO010032s
join y in db.MOP1042s on x.MANUFACTUREORDER_I equals y.MANUFACTUREORDER_I into x_y
where x.STRTDATE == selectedDate && (x.MANUFACTUREORDERST_I == 2 || x.MANUFACTUREORDERST_I == 3)
from y in x_y.DefaultIfEmpty()
select new ProductionSchedule()
{
MO = x.MANUFACTUREORDER_I,
BOMNAME = x.BOMNAME_I,
SpaModel = x.ITEMNMBR,
MoldType = GetMoldType(x.ITEMNMBR.Trim()),
SerialNumber = y.SERLNMBR,
Difficulty = GetModelDifficulty(x.ITEMNMBR)
}).ToList();
return spaList.OrderByDescending(x => x.Difficulty).ToList();
}
public string GetMoldType(string model)
{
return db.SkuModelDatas.Where(x => x.Value == model).Select(x => x.MoldType).FirstOrDefault();
}
public decimal GetModelDifficulty(string model)
{
decimal difficulty = (String.IsNullOrEmpty(model)) ? 0M : Convert.ToDecimal(db.SkuModelDatas.Where(x => x.Value == model.Trim()).Select(x => x.Difficulty).FirstOrDefault());
return difficulty;
}
Why it worked when trapping for null string for x.ITEMNMBR (model parameter) in one method and not the other and needing to OrderByDescending outside of the main LINQ query, I have no idea.
Thanks for all the suggestions and help with this.
The problem is your query is calling code that LINQ cannot translate into SQL.
First try this, it may help. There may be a problem with your (decimal) cast. Modify your method GetModelDifficulty to the following:
public decimal GetModelDifficulty(string model)
{
return Convert.ToDecimal(db.SkuModelDatas.Where(x => x.Value == model).Select(x => x.Difficulty).FirstOrDefault());
}
If that doesn't work I'm afraid you'll have to break your query down further to narrow down the issue. Use the documentation provided here: Standard Query Operator Translation (LINQ to SQL) to be sure that any extension methods you are using have supported translations.
If you run into a piece of code that cannot be translated, you may need to declare a separate variable with the necessary value already stored inside of it, that you can then use inside of your query.
I think it's because your call to FirstOrDefault() can return a null value. When you assign to a typed object you can use ? operator to signify that it can be null:
decimal? myDec = <some code returning decimal value or null>
Then you can check if myDec is null or not by:
myDec.HasValue