I have code to retrieve all columns from a entity class against a search criteria. But I want a specific column value instead of complete column values.
My code is -
Main main;
main = repo.Find<Main>(m => m.Code == criteria.code);
where Main is entity class, repo is repository and criteria is search criteria class. Now I want to get a specific column name, say id. How can I achieve this?
Assuming that Find is returning an IQueryable<T>, then you can use a projection:
repo.Find<Main>(m => m.Code == criteria.code).Select(m => m.Column);
var column =
from m in repo
where m.Code == criteria.code
select m.SomeColumn;
You do a query projection with the Select method:
repo.Mains.Where(m => m.Code == criteria.code).Select(m => m.Id);
On a related note, you should read Getting Started with Entity Framework. It'll give you a good idea of the query operators.
Related
Hi All I am trying to do below ,I want to load an attribute value like this .
var date = db.GetTable<bbb>().Where(x => idList.Contains(x.MID))
.Select(x => x.ModifiedDate).FirstOrDefault;
var test = db.GetTable<nnn>().Where(x => xguy.Distinct().Contains(x.SID))
.LoadWith(x => x.Modified == lastPostDate);
exception:-
LinqToDB.LinqToDBException: 'Expression '(x.Modified == value(vv.x+<>c__DisplayClass25_1).lastPostDate)' is not an association.'
How can I do this?
I used the FirstOrDefault option to get one value, but I do not understand about Expression is not an association.
Your use of the "LoadWith" method is suspicious here.
LoadWith is a specialized function to load additional table data that is linked (e.g. via foreign key) to the current table row.
Based on your usage, it looks like you're just trying to set up another "Where" clause, so instead of
.LoadWith(x => x.Modified == lastPostDate);
you wanted
.Where(x => x.Modified == lastPostDate);
or alternatively, combine this with your prior Where statement to simplify things:
var test = db.GetTable<nnn>().Where(x => x.Modified == lastPostDate &&
xguy.Distinct().Contains(x.SID));
Let me know if this isn't what you intended. If this is the case, perhaps you have an SQL statement or similar that you are now trying to translate to C# LINQ, or can otherwise explain in plain English what this statement was meant to accomplish?
I have a simple scenario.I want to list out all the employees except the logged in user.
Similar SQL Condition is
select * from employee where id not in(_loggedUserId)
How can I acheive the above using LINQ.I have tried the following query but not getting the desired list
int _loggedUserId = Convert.ToInt32(Session["LoggedUserId"]);
List<int> _empIds = _cmn.GetEmployeeCenterWise(_loggedUserId)
.Select(e => e.Id)
.Except(_loggedUserId)
.ToList();
Except expects argument of type IEnumerable<T>, not T, so it should be something like
_empIds = _cmn.GetEmployeeCenterWise(_loggedUserId)
.Select(e => e.Id)
.Except(new[] {_loggedUserId})
.ToList();
Also note, this is really redundant in the case when exclusion list contains only one item and can be replaces with something like .Where(x => x != _loggedUserId)
Why not use a very simple Where condition?
_empIds = _cmn.GetEmployeeCenterWise(_loggedUserId).Where(e=>e.Id != _loggedUserId).ToList();
The title of your question is how to perform a not in query against a database using LINQ. However, as others have pointed out your specific problem is better solved by a using users.Where(user => user.Id != loggedInUserId).
But there is still an answer on how to perform a query against a database using LINQ that results in NOT IN SQL being generated:
var userIdsToFilter = new[] { ... };
var filteredUsers = users.Where(user => !userIdsToFilter.Contains(user.Id));
That should generate the desired SQL using either Entity Framework or LINQ to SQL.
Entity Framework also allows you to use Except but then you will have to project the sequence to ID's before filtering them and if you need to original rows you need to fetch them again from the filtered sequence of ID's. So my advice is use Where with a Contains in the predicate.
Use LINQ without filtering. This will make your query execute much faster:
List<int> _empIds = _cmn.GetEmployeeCenterWise(_loggedUserId)
.Select(e => e.Id).ToList();
Now use List.Remove() to remove the logged-in user.
_empIds.Remove(_loggedUserId);
Assuming following tables
Person
id
name
PersonTeam
id
person_id
is_supervisor
team_id
Team
id
TimeSheet
id
team_id
I would like to obtain all TimeSheets for a supervisor. I got name of supervisor, then I need select which team he is got supervisor role. Then select all time sheet of those teams.
I believe following query does
var allTimeSheets = ctx.PersonTeam.Where(y => y.Person.name == supervisor_name).Where(x => x.is_supervisor == true).Select(z => z.Team).Select(t => t.TimeSheet);
afer this operation I cannot understand allTimeSheets is a
IQueryable<ICollection<TimeSheet>>
I expected more a
<ICollection<TimeSheet>>
or any IEnumrable.
Then questions are :
why I got that kind of result ?
how to obtain TimeSheet[] where I got IQueryable < ICollection < TimeSheet > > ?
why did I get that kind of result ? I expected more a ICollection<TimeSheet>
An IQueryable<T> is an IEnumerable<T>. The reason it's returning an IQueryable is so you can chain other methods like OrderBy onto it and project those to the actual SQL.
I just realized what you're asking. To "flatten" the collection of collections, use SelectMany instead of two chained Selects:
var allTimeSheets = ctx.PersonTeam
.Where(y => y.Person.name == supervisor_name
&& y.is_supervisor == true)
.SelectMany(z => z.Team, (z, t) => t.TimeSheet);
The answer to your second question still applies:
how do I obtain a TimeSheet[] from a IQueryable<ICollection<TimeSheet>>
(first of all use the first part to change to an IQueryable<TimeSheet>)
You can call one of the "conversion" methods like ToArray, ToList, to "hydrate" the query into a concrete type.
You can also call "AsEnumerableto cast to anIEnumerableto convert the query to Linq-To-Objects, which has better support for custom functions in sorts, filters, etc. Note that callingAsEnunerable` does no immediately fetch the objects, but will do as as soon as the collection in enumerated.
I have got a bit of an issue and was wondering if there is a way to have my cake and eat it.
Currently I have a Repository and Query style pattern for how I am using Linq2Sql, however I have got one issue and I cannot see a nice way to solve it. Here is an example of the problem:
var someDataMapper = new SomeDataMapper();
var someDataQuery = new GetSomeDataQuery();
var results = SomeRepository.HybridQuery(someDataQuery)
.Where(x => x.SomeColumn == 1 || x.SomeColumn == 2)
.OrderByDescending(x => x.SomeOtherColumn)
.Select(x => someDataMapper.Map(x));
return results.Where(x => x.SomeMappedColumn == "SomeType");
The main bits to pay attention to here are Mapper, Query, Repository and then the final where clause. I am doing this as part of a larger refactor, and we found that there were ALOT of similar queries which were getting slightly different result sets back but then mapping them the same way to a domain specific model. So take for example getting back a tbl_car and then mapping it to a Car object. So a mapper basically takes one type and spits out another, so exactly the same as what would normally happen in the select:
// Non mapped version
select(x => new Car
{
Id = x.Id,
Name = x.Name,
Owner = x.FirstName + x.Surname
});
// Mapped version
select(x => carMapper.Map(x));
So the car mapper is more re-usable on all areas which do similar queries returning same end results but doing different bits along the way. However I keep getting the error saying that Map is not able to be converted to SQL, which is fine as I dont want it to be, however I understand that as it is in an expression tree it would try to convert it.
{"Method 'SomeData Map(SomeTable)' has no supported translation to SQL."}
Finally the object that is returned and mapped is passed further up the stack for other objects to use, which make use of Linq to SQL's composition abilities to add additional criteria to the query then finally ToList() or itterate on the data returned, however they filter based on the mapped model, not the original table model, which I believe is perfectly fine as answered in a previous question:
Linq2Sql point of retrieving data
So to sum it up, can I use my mapping pattern as shown without it trying to convert that single part to SQL?
Yes, you can. Put AsEnumerable() before the last Select:
var results = SomeRepository.HybridQuery(someDataQuery)
.Where(x => x.SomeColumn == 1 || x.SomeColumn == 2)
.OrderByDescending(x => x.SomeOtherColumn)
.AsEnumerable()
.Select(x => someDataMapper.Map(x));
Please note, however, that the second Where - the one that operates on SomeMappedColumn - will now be executed in memory and not by the database. If this last where clause significantly reduces the result set this could be a problem.
An alternate approach would be to create a method that returns the expression tree of that mapping. Something like the following should work, as long as everything happening in the mapping is convertible to SQL.
Expression<Func<EntityType, Car>> GetCarMappingExpression()
{
return new Expression<Func<EntityType, Car>>(x => new Car
{
Id = x.Id,
Name = x.Name,
Owner = x.FirstName + x.Surname
});
}
Usage would be like this:
var results = SomeRepository.HybridQuery(someDataQuery)
.Where(x => x.SomeColumn == 1 || x.SomeColumn == 2)
.OrderByDescending(x => x.SomeOtherColumn)
.Select(GetCarMappingExpression());
i have a table called orders and i have a column called Last Update (and an order object with a LastUpdate property). I want to construct a query using nhibernate to get the last 50 rows so i don't go to the database and get everything and then have to filter results in my application.
is this possible in nhibernate. I am trying to use the LINQ api
Here's the LINQ version of this query.
var orders = session.Query<Order>()
.OrderByDescending(x => x.LastUpdate)
.Take(50);
Here's the screen shot of the code sample...
Here's the screen shot from NHibernate Profiler...
If you are using a Criteria then use SetMaxResults(50) and do a descending sort on the date time.
You can use SetMaxResults(50), although depending on which 50 rows you want (latest? first? last?) you'll probably also need to do a SortBy expression as well.
var orders = session.Query<Linq>()
.OrderByDescending(x => x.LastUpdate)
.Take(50);
In general case suggesing LastUdate can be nullable using Linq2SQL you may write extension method to your IQueriable:
public static partial class FooTable
{
public static IQueryable<FooTable> LastUpdated(this IQueryable<FooTable> queryable, int count)
{
return queryable.Where(x => (x.LastUdate != null))
.OrderByDescending(x => x.LastUdate)
.Take(count);
}
}