EF Core Select query with null references - entity-framework-core

I have a Select query that performs a check on a child navigation property to then check another referenced property. The first child navigation property can be null but the second property isRequired() and if the first child is not null in the database, the query runs fine but if one or more rows exist that do not have a referencing value for that property then I get -
An exception occurred while iterating over the results of a query
for...
How can I make a query with an optional property run and return null for the records that have no references.
await _dbContext.NewsBoard
.AsNoTracking()
.Select(item => new NewsResponse
{
Id = item.BoardId,
MediaType = new MediaTypeResponse
{
Id = item.Media.MediaTypeId,
Name = item.Media.MediaType.Name
},
Above is the query I am trying to run, the item.Media does not exist have a value for its foreign key (its null) and so the expected result would have been a list of NewsResponse with MediaType being null where there is a null referenced item.Media.

Use a null check in your query like -
await _dbContext.NewsBoard
.AsNoTracking()
.Select(item => new NewsResponse
{
Id = item.BoardId,
MediaType = item.Media == null ? null : new MediaTypeResponse // null check
{
Id = item.Media.MediaTypeId,
Name = item.Media.MediaType.Name
}
})
.ToList();

Related

IQueryable throws null ref Exception while using FirstOrDefault(where) [duplicate]

This question already has answers here:
What is a NullReferenceException, and how do I fix it?
(27 answers)
Closed 4 years ago.
I am doing a repository call in EF, as soon as i access First or default i am getting null reference exception, could any body help with inputs?
is there any way to check if the Entity values are null? so that i can avoid Exception.
public TEntity GetSingle(Func<TEntity, bool> where, params Expression<Func<TEntity, object>>[] navigationProperties)
{
TEntity item = null;
using (var context = new CDREntities())
{
IQueryable<TEntity> dbQuery = context.Set<TEntity>();
below line returns 56 entities with null values, because i dont have any entities in the table
//Apply eager loading
dbQuery = navigationProperties.Aggregate(dbQuery, (current, navigationProperty) => current.Include(navigationProperty));
below is the place where i get null reference exception when i access above null entities, is there any thing wrong with the below statement?
item = dbQuery
.AsNoTracking() //Don't track any changes for the selected item
.FirstOrDefault(where); //Apply where clause
}
return item;
}
Have you tried checking whether it is null or not
if(item == null)
{
// Handle null case
}
The query is simple, FirstOrDefault will return the first item in a db, or the first item in a collection of results, if there are no items in the table being queried, naturally there's nothing for EF to return.
EF handles such cases by returning null as it's appropriate. Simply check if the response is null, the only other way to avoid it is to have something in the database for it to return or performing a count operation against the table its self which is pointless if you are then going to have to query the table again for the data you just checked for it existing or not.
Also why are you creating a method called Single? The implementation of it is wrong for one, secondly the Single method exposed in Entity Framework behaves differently, it will throw an exception if more than 1 item matches the query.
Another point I'm wondering is why you're receiving 56 null items if your table is empty???

JPQL: How to write dynamic where conditions

I am struggling with JPQL dynamic where condition. I tried searching the syntax for the same but coluldn't find one.
in my case if user is passing the name parameter then the select query should be
select * from user where name = 'sanjay'
if user is not passing name parameter then select query should be
select * from user
Below is my jpql query format which fails when name parameter is not passed.
entity_manager.createQuery("select u from user u where u.name = :name").setParameter("name",params[:name]).getResultList()
How can i update above JPQL query to support both the cases i.e when the name parameter is passed and when the name parameter is not passed ??
This is not possible in JPQL. You even cannot do something like
createQuery("select u from user u where u.name = :name OR :name IS NULL")
It is not possible. That simple. Use two queries or use the Criteria API.
This is the answer I get when I tries to do like you it is working with some modification.
In my case I had the problem that my optional parameter was a List<String> and the solution was the following:
#Query(value = "SELECT *
FROM ...
WHERE (COLUMN_X IN :categories OR COALESCE(:categories, null) IS NULL)"
, nativeQuery = true)
List<Archive> findByCustomCriteria1(#Param("categories") List<String> categories);
This way:
If the parameter has one or more values it is selected by the left side of the OR operator
If the parameter categories is null, meaning that i have to select all values for COLUMN_X, will always return TRUE by the right side of the OR operator
Why COALESCE and why a null value inside of it?
Let's explore the WHERE clause in all conditions:
Case 1: categories = null
(COLUMN_X IN null OR COALESCE(null, null) IS NULL)
The left part of the OR will return false, while the right part of the OR will always return true, in fact COALESCE will return the first non-null value if present and returns null if all arguments are null.
Case 2: categories = ()
(COLUMN_X IN null OR COALESCE(null, null) IS NULL)
JPA will automatically identify an empty list as a null value, hence same result of Case 1.
Case 3: categories = ('ONE_VALUE')
(COLUMN_X IN ('ONE_VALUE') OR COALESCE('ONE_VALUE', null) IS NULL)
The left part of the OR will return true only for those values for which COLUMN_X = 'ONE_VALUE' while the right part of the OR will never return true, because it is equals to 'ONE_VALUE' IS NULL (that is false).
Why the null as second parameter? Well, that's because COALESCE needs at least two parameters.
Case 4: categories = ('ONE_VALUE', 'TWO_VALUE')
(COLUMN_X IN ('ONE_VALUE', 'TWO_VALUE') OR COALESCE('ONE_VALUE', 'TWO_VALUE', null) IS NULL)
As in Case 3, the left part of the OR operator will select only the rows for which COLUMN_X is equale to 'ONE_VALUE' or 'TWO_VALUE'.

How to filter the OrderBy

i am retrieving data from database on the base of there id, as can be seen,
public ActionResult loadEpisodes(int id, string name, int epId)
{
ViewBag.LoadEps = db.VideoEpisode
.Where(ve => ve.VideoId == id && ve.IsActive == true)
.OrderByDescending(c => c.Sequence);
//some other code removed for the ease
return view();
}
It will return the episodes of some 'id' and in descending sequence value.
My question is, if there is way to retrieve the data in descending order but order must starts from the episode id 'epId'
I have tried the above method but failed
ViewBag.LoadEps = db.VideoEpisode
.Where(ve => ve.VideoId == id && ve.IsActive == true)
.OrderBy(c=>c.Sequence)
.First(c=> c.VideoEpisodeId ==epId);
EDIT: If I understand the problem correctly, you want the order to be a given episode with Id epId first, then a list ordered by sequence.
I'm not sure it can be done in one Linq query.
How about creating a new list, putting your chosen VideoEpisode in as the first element, and then appending a sorted list of the other episodes after that. Something like:
var Loadeps = new List<VideoEpisode>();
Loadeps.Add(db.VideoEpisode.First(c=> c.VideoEpisodeId ==epId));
Loadeps.Add(db.VideoEpisode
.Where(ve => ve.VideoId == id && ve.IsActive == true && c.VideoEpisodeId != epId)
.OrderByDescending(c => c.Sequence)).toList();

Entity Framework How To Load Primary Key Only

Is it possible to load only specific attributes of a class, such as only the primary key, without fetching the other attribute values?
I need to get an object from the DB but only have the ID value populated, all other attributes are not needed.
If another attribute is requested, the rest of the object needs to be loaded.
Yes you can and technique is called "Projection"
e.g.
var filteredData = context.Entity
.Where(p => p.ID == 1 ) // just an example filter
.Select(p => new Entity
{
ID = p.ID,
})
.ToList();
If if helps dont forgot to vote and mark it as answer :)

Entity query increments field value for every query (field is not autoincremented)

I have an entity query that when I run increments the value of my field. I am using entity framework and sql server 2012. Here is my query;
public void GetLastAccountNumber(ProductLine productLine, Action completed)
{
EntityQuery query = WASMDomainContext.GetContactCustomerAccountsQuery()
.Where(cca => cca.ProductLineId == productLine.Id)
.OrderBy(cca => cca.AccountNumber);
WASMDomainContext.Load(query, loadOp =>
{
Exception error = null;
ContactCustomerAccount lastAccount = null;
if (loadOp.HasError)
error = loadOp.Error;
else
lastAccount = loadOp.Entities.LastOrDefault();
// Invoke completion callback
completed(lastAccount, error);
}, null);
}
Query should return the last account number which is an integer field for now. However it returns an incremented value. For example in my table I have an accountnumber 0 the query returns an entity with account number as 1. My account number field is not auto increament and I find this very strange. And each time the above is called the AccountNumber field value increases by one but the database value will remain 0. I just want the query to return what is in my database. Any idea why this could be happening? Any help will be appreciated. Thank you all.