Entity Framework check result null - entity-framework

I am using this query:
var result = from r in db.Registrations
join u in db.UserTypes on r.UserTypeId equals u.UserTypeId
where r.Email.ToLower()==model.LoginEmail.ToLower() && r.Password.ToLower() == model.Password.ToLower()
select new { r,u};
Here how can I check that if no record is found? If so, then
if(result == null)
// no record found
else
// record found

You can use Any or Count extension method:
if(!result.Any())
///norecord found
else
//record found
Using Count would be:
if(result.Count()==0)
///norecord found
else
//record found

First what you assign to a result is just IQueryable so it's query and you need to execute it first. So I suggest renaming it to query and then do it like this:
var query= from r in db.Registrations
join u in db.UserTypes on r.UserTypeId equals u.UserTypeId
where r.Email.ToLower()==model.LoginEmail.ToLower() && r.Password.ToLower() == model.Password.ToLower();
select new { r,u};
var result = query.FirstOrDefault(); // gives first result or null
if (result == null) {
// no record
} else {
// record found and is in result
}

Related

LINQ to Entities query to verify all rows exist

I have a need to verify that all the rows in a given set exist in the database and the current user has access to all the rows. I'd like to do this in a single query to the database, something like a .All() query but I can't quite come up with the right syntax (maybe it's not possible).
The iterative version of the code would look like:
bool canAccess;
foreach(var taskId in taskIds)
{
canAccess = await DataContext.WorkTasks.AnyAsync(wt => wt.DealerId == dealerId && wt.Id == taskId);
if(!canAccess) break;
}
I was thinking about something like:
var canAccess = await DataContext.WorkTasks.AllAsync(wt => wt.DealerId == dealerId && taskIds.Contains(wt.Id));
But I don't think that's what I want. Can this be done using LINQ?
Something like this:
var dbCount = await DataContext.WorkTasks.Where(wt => wt.DealerId == dealerId && taskIds.Contains(wt.Id)).Count();
Will send all your IDs to the server and count the matching rows.
To combine into a single query:
var q = DataContext.WorkTasks.Take(0); // setup q to right type
foreach (var taskId in taskIds)
q = q.Concat(DataContext.WorkTasks.Where(wt => wt.Id == taskId && wt.DealerId == dealerId));
var canAccess = (taskIds.Count() == q.Count());

Valid Postgres query alway return undefined

I am using sails to build an API, one of my function needs to get columns from my PGSQL database. My SQL request is working when I test it in PGadmin, it looks like this :
SELECT "user".id, "user".picture, "user".first_name, "trophe".trophe FROM "user" INNER JOIN "trophe" ON "trophe".user = "user".id WHERE "trophe".foot = 1
When I transcript this request in my sails API, it looks like this :
getHommeAndChevre: function (req, res) {
console.log(req.param("id"));
Trophe.query("SELECT 'user'.id, 'user'.picture, 'user'.first_name, 'trophe'.trophe FROM 'user' INNER JOIN 'trophe' ON 'trophe'.user = 'user'.id WHERE 'trophe'.foot ="+req.param('id'), function(err,trophes){
if(!trophes) {return res.status(400).end();}
if(trophes){
_each(trophes, function(trophe){
if (trophe.trophe == 0) {var chevre = trophe};
if (trophe.trophe == 1) { var homme = trophe};
})
return res.status(200).json({chevre: chevre, homme: homme})
}
});
}
However whatever I do the Trophe.query always returned undefined. What could be wrong here ?
Your return is outside the callback , so you return the value before the end of the query.
_each(trophes, function(trophe, index){
if (trophe.trophe == 0) {var chevre = trophe};
if (trophe.trophe == 1) { var homme = trophe};
if (index == trophes.length - 1) //End of the loop
return res.status(200).json({chevre: chevre, homme: homme});
})
Use double quotes for identifiers
Trophe.query('SELECT "user".id, "user".picture, "user".first_name, ...

how to debug EF 5 null reference exception?

I am getting a null refrence exception when im filtering EF but I am absolultely clueless.
public IEnumerable<TonalityBatchModel> GetTonalityBatch(int briefID)
{
try
{
var brief = NeptuneUnitOfWork.Briefs.FindWhere(b => b.ID == briefID).FirstOrDefault();
if (brief != null && brief.TonalityCriteria != null)
{
return brief.TonalityCriteria.TonalityBatches
.Select(b => new TonalityBatchModel()
{
BriefID = b.BriefID,
Status = b.TonalityCriteria.IsActive == true ?"Active":"Ended",
BatchID = b.ID,
CompetitorID = b.BriefCompetitorID,
Competitor = brief.BriefCompetitors.Where(i=>i.ID == b.BriefCompetitorID).Select(c=>c.Organisation.Name).First(),
Size = b.BatchSize,
StartDate = b.StartDate,
EndDate = b.EndDate,
IsPublished = b.Lookup_TonalityBatchStatus.ID == (int)TonalityBatchStatus.Published?"Yes":"No",
IsCompleted = b.Lookup_TonalityBatchStatus.ID == (int)TonalityBatchStatus.Completed ? "Yes" : "No",
IsAssigned = b.Lookup_TonalityBatchStatus.ID == (int)TonalityBatchStatus.Allocated ? "Yes" : "No",
ImportantCount = b.TonalityItems.Count(i=> i.IsImportant),
ArticlesCount = b.TonalityItems.Count,
FavourableCount = b.TonalityItems.Count(i => i.Lookup_TonalityScoreTypes.ID ==(int)TonalitySourceType.Favourable),
UnfavourableCount = b.TonalityItems.Count(i => i.Lookup_TonalityScoreTypes.ID ==(int)TonalitySourceType.Unfavourable),
NeutralCount = b.TonalityItems.Count(i => i.Lookup_TonalityScoreTypes.ID ==(int)TonalitySourceType.Neutral)
}).ToList();
}
return new List<TonalityBatchModel>();
}
catch (Exception ex)
{
Logger.Error(ex);
throw;
}
}
You'll need to reduce your query to a simpler query, and then start building it back up again until the NullReferenceException occurs. Looking at your code, here are some likely places (I'm making some assumptions since I don't know everything about your model):
Competitor = brief.BriefCompetitors.Where(i=>i.ID == b.BriefCompetitorID).Select(c=>c.Organisation.Name).First()
BriefCompetitors could be null. c.Organisation could be null.
IsPublished = b.Lookup_TonalityBatchStatus.ID == (int)TonalityBatchStatus.Published?"Yes":"No",
(and other similar lines) b.Lookup_TonalityBatchStatus might be null.
ImportantCount = b.TonalityItems.Count(i=> i.IsImportant),
(and other similar lines) b.TonalityItems might be null.
I believe this is because your count is returning null records. I could be wrong but the SQL that's being produced here is something like:
INNER JOIN TonalityItems i on i.Lookup_TonalityScoreTypes == x
Where x is the value of (int)TonalitySourceType.Favourable. Because this join has no matching results there is nothing to do a count on. You could try adding ?? 0 to the end of the query:
FavourableCount = b.TonalityItems.Count(i => i.Lookup_TonalityScoreTypes.ID ==(int)TonalitySourceType.Favourable) ?? 0,

Linq to Entities: multiple criteria query for one table

using (WinFileContextContainer c = new WinFileContextContainer())
{
IQueryable<File> dbfiles = (from f in c.File
where //(f.Category.Any((category => category.name == categoryname)) &&
f.alive //&&
//f.description == "" &&
//f.Category.Count == 1)
select f);
// the rest....
}
The query works only as it is now - I left just one criteria (the rest is in comment sections). But I want the other criteria to be taken into account too. I tried with multiple "where"s :D or all the criteria in brackets with one "where", but still no success. I'm kinda new to LINQ so any help is appreciated. Thanks in advance !
Finally got it to work:
IQueryable<File> dbfiles =
c.File.Where(f => f.Category.Any(cat => cat.name == categoryname) &&
f.alive &&
f.description == null &&
f.Category.Count == 1);

Using an existing IQueryable to create a new dynamic IQueryable

I have a query as follows:
var query = from x in context.Employees
where (x.Salary > 0 && x.DeptId == 5) || x.DeptId == 2
order by x.Surname
select x;
The above is the original query and returns let's say 1000 employee entities.
I would now like to use the first query to deconstruct it and recreate a new query that would look like this:
var query = from x in context.Employees
where ((x.Salary > 0 && x.DeptId == 5) || x.DeptId == 2) && (x,i) i % 10 == 0
order by x.Surname
select x.Surname;
This query would return 100 surnames.
The syntax is probably incorrect, but what I need to do is attach an additional where clause and modify the select to a single field.
I've been looking into the ExpressionVisitor but I'm not entirely sure how to create a new query based on an existing query.
Any guidance would be appreciated. Thanks you.
In an expression visitor you would override the method call. Check if the method is Queryable.Where, and if so, the methods second parameter is a quoted expression of type lambda expression. Fish it out and you can screw with it.
static void Main()
{
IQueryable<int> queryable = new List<int>(Enumerable.Range(0, 10)).AsQueryable();
IQueryable<string> queryable2 = queryable
.Where(integer => integer % 2 == 0)
.OrderBy(x => x)
.Select(x => x.ToString());
var expression = Rewrite(queryable2.Expression);
}
private static Expression Rewrite(Expression expression)
{
var visitor = new AddToWhere();
return visitor.Visit(expression);
}
class AddToWhere : ExpressionVisitor
{
protected override Expression VisitMethodCall(MethodCallExpression node)
{
ParameterExpression parameter;
LambdaExpression lambdaExpression;
if (node.Method.DeclaringType != typeof(Queryable) ||
node.Method.Name != "Where" ||
(lambdaExpression = ((UnaryExpression)node.Arguments[1]).Operand as LambdaExpression).Parameters.Count != 1 ||
(parameter = lambdaExpression.Parameters[0]).Type != typeof(int))
{
return base.VisitMethodCall(node);
}
return Expression.Call(
node.Object,
node.Method,
this.Visit(node.Arguments[0]),
Expression.Quote(
Expression.Lambda(
lambdaExpression.Type,
Expression.AndAlso(
lambdaExpression.Body,
Expression.Equal(
Expression.Modulo(
parameter,
Expression.Constant(
4
)
),
Expression.Constant(
0
)
)
),
lambdaExpression.Parameters
)
)
);
}
}
}