I have used this query to get the user and his list of followers
var userAndFollowersQuery =
from us in _unitOfRepository.User.Where(i => i.Index == currentUserId)
let fl = _unitOfRepository.TradingAccount
.Where(i => !i.IsMaster && i.IsActive && i.UserId == us.Index)
.ToList()
select new
{
User = new
{
us.Index,
us.AccountBalance
},
Followers = fl
};
var userAndFollowers = await userAndFollowersQuery.FirstOrDefaultAsync(cancellationToken);
But EF framework throw me the below exception
The LINQ expression 'i => !(i.IsMaster) && i.IsActive && i.UserId == EntityShaperExpression:
BackOffice.Service.Data.Models.User
ValueBufferExpression:
ProjectionBindingExpression: Outer
IsNullable: False
.Index' could not be translated. Either rewrite the query in a form that can be translated, or switch to client evaluation explicitly by inserting a call to 'AsEnumerable', 'AsAsyncEnumerable', 'ToList', or 'ToListAsync'. See https://go.microsoft.com/fwlink/?linkid=2101038 for more information.
I guess this was caused by the fl object which was not translated to SQL, it has taken me quite long finding a solution by far. Any help would be appreciated, thank you guys.
The question doesn't contain EF. EF neither has nor needs "repositories" and "units of work" as a DbContext already is a multi-entity Unit-of-Work, a DbSet already is a single-entity Repository. They aren't CRUD DAOs. Objects that provide single record access and CRUD operations are Data Access Objects, not repositories.
The error complains that
i => !(i.IsMaster) && i.IsActive && i.UserId == EntityShaperExpressioncan't be translated. That's because, assuming_unitOfRepository.Userand_unitOfRepository.TradingAccountreturn IQueryable's, there are two independent queries. The one onTradingAccountis trying to use the one produced from_unitOfRepository.User.Where(i => i.Index == currentUserId)without knowing whether the queries are related or not.This seems to be an attempt to recreate a correlated subquery in LINQ. There's no need for this. LINQ isn't SQL and a DbContext isn't a database connection. LINQ is EF's query language. EF itself will translate a LINQ query to SQL using the schema and relations configured in the DbContext. There's no need for JOINs or correlated subqueries if the classes have properties.
Normally, the
Userobject should have aList<TradingAccount> TradingAccounts {get;set;}property. Assuming the classes follow EF's naming conventions, EF will be able to guess the relations just by the type and property names. Which is whyIndexis a bad idea. ID means Identity, not Index.This allows writing the following queries:
In query form:
or, if we want to load the entire user object:
This would eagerly load only the
TradingAccounts that match the filter