I would like to add a single item to the results of a linq query. I know it's not possible to join a local source and a SQL source. So, is it possible to construct a query to do the same as this?
SELECT ID FROM Types
UNION
SELECT 1
The best I've come up with is this:
List<int> OrgList = DBContext.Types.Select(b => b.ID).ToList();
OrgList.Add(1);
but I'd rather add the item beforehand and still have an IQueryable. Or is there a good reason to not do it this way?
You must get the data from the db and then add the new item like you have done in your code.
The only way to have an IQueryable would be to deffer the adding of the new item to the point were the query is resolved.
You can use Union:
var query = DBContext.Types.Select(b => b.ID).ToList().Union(new[]{1});
Not tested but it should work
Try Concat
var result = DBContext.Types.Select(p => p.ID)
.Concat(new List<int>() { 1 }).ToList();
Related
This is the problematic code:
var distinctCatNames = allCats.Select(c => c.CatName).Distinct();
if (skip.HasValue) distinctCatNames = distinctCatNames .Skip(skip.Value);
if (take.HasValue) distinctCatNames = distinctCatNames .Take(take.Value);
var distinctCatNameList= distinctCatNames .ToList();
If you imagine I have a list of 100 cats, I want to select the 10 distinct names. It's going into a paged list so it has to use skip and take.
The above won't work, because it has to be ordered with OrderBy.
If I put the OrderBy after the distinct, I can't do Skip and Take because the result is an IOrderedQueryable, not an IQueryable (compiler error).
If I do it before, the error says DbSortClause expressions must have a type that is order comparable.
I need to make sure that under the hood it's translating my query properly, because there may be a lot of cats so I want to ensure it generates SQL that incorporates the skip/take in the query rather than getting ALL cats and then doing it on that collection.
Any ideas?
You need to order the items but then simply type the variable you store it in as an IQueryable, rather than an IOrderedQueryable:
var distinctCatNames = allCats.Select(c => c.CatName)
.Distinct()
.OrderBy(name => name)
.AsQueryable();
I have a query as follows:
var paymentInfo =
from i in dbconnect.tblPayments
where i.tenderId == _tenderId
select i;
This query has some results, but I need to add an additional result that I already have, from the variable PaymentInfo.
For example suppose that my query has 2 results i need to add another result to "PaymentInfo" using linq.
I thought that the result is a kind of list, and that I could call .Add(PaymentInfo), but this doesn't work
How can I do this?
You can use Concat to concat another sequence to the end of this one.
var paymentInfo = paymentInfo.Concat(someOtherPayments);
I thought that the result is a kind of list
No, the result is an IEnumerable<T> which is read-only. You can create a list by calling .ToList() and then add an item to it.
var paymentInfo = (from i in dbconnect.tblPayments
where i.tenderId == _tenderId
select i).ToList();
paymentInfo.Add(existingPayment);
I'm trying to write a query that grabs a list of countries out from my joined data.
Places is List<Country>.
var zonedCountries = (from dz in db.DeliveryZones.Include(d => d.Places)
where model.DeliveryZones.Contains(dz.ID)
select dz.Places);
I would expect zonedCountries to be a List but instead it is a IQueryable<ICollection<Country>>.
How do I extract the list from this?
If you want to get flattened list of countries:
var zonedCountries = (from dz in db.DeliveryZones.Include(d => d.Places)
where model.DeliveryZones.Contains(dz.ID)
from p in dz.Places
select p);
Or use SelectMany:
var zonedCountries = db.DeliveryZones.Include(d => d.Places)
.Where(dz => model.DeliveryZones.Contains(dz.ID))
.SelectMany(dz => dz.Places);
BTW I'm not sure if you need to include places manually in this case (thus you are selecting places instead of delivery zones). And you will probably want to select distinct countries only - Distinct() will help you here. Also if you want to store results in list, then simple ToList() call will do the job.
This is the gist of my query which I'm testing in LinqPad using Linq to Entity Framework.
In my mind the resultant SQL should begin with something like SELECT TableA.ID AS myID. Instead, the SELECT includes all fields from all of the tables. Needless to say this incurs a massive performance hit among other problems. How can I prevent this?
var AnswerList = this.Answers
.Where(x=>
..... various conditions on x and related entities...
)
.GroupBy(x => new {x.TableA,x.TableB,x.TableC})
.Select(g=>new {
myID = g.Key.TableA.ID,
})
AnswerList.Dump();
In practice I'm using a new type instead of an anonymous one but the results are the same either way.
Let me know if you need me to fill in more of the ...'s.
UPDATE
I've noticed I can prevent this problem by explicitly specifying the fields I want returned in the GroupBy method, e.g. new {x.TableA.ID ... }
But I still don't understand why it doesn't work just using the Select method (which DOES work when doing the equivalent in Linq to SQL).
Hi,
Could you please try below....?
var query = from SubCat in mySubCategory
where SubCat.CategoryID == 1
group 1 by SubCat.CategoryID into grouped
select new { Catg = grouped.Key,
Count = grouped.Count() };
Thank you,
Vishal Patel
Say you have columns AppleType, CreationDate and want to order each group of AppleType by CreationDate. Furthermore, you want to create a new column which explicitly ranks the order of the CreationDate per AppleType.
So, the resulting DataSet would have three columns, AppleType, CreationDate, OrderIntroduced.
Is there a LINQ way of doing this? Would I have to actually go through the data programmatically (but not via LINQ), create an array, convert that to a column and add to the DataSet? I have there is a LINQ way of doing this. Please use LINQ non-method syntax if possible.
So are the values actually appearing in the right order? If so, it's easy - but you do need to use method syntax, as the query expression syntax doesn't support the relevant overload:
var queryWithIndex = queryWithoutIndex.Select((x, index) => new
{
x.AppleType,
x.CreationDate,
OrderIntroduced = index + 1,
});
(That's assuming you want OrderIntroduced starting at 1.)
I don't know offhand how you'd then put that back into a DataSet - but do you really need it in a DataSet as opposed to in the strongly-typed sequence?
EDIT: Okay, the requirements are still unclear, but I think you want something like:
var query = dataSource.GroupBy(x => x.AppleType)
.SelectMany(g => g.OrderBy(x => x.CreationDate)
.Select((x, index ) => new {
x.AppleType,
x.CreationDate,
OrderIntroduced = index + 1 }));
Note: The GroupBy and SelectMany calls here can be put in query expression syntax, but I believe it would make it more messy in this case. It's worth being comfortable with both forms.
If you want a pure Linq to Entities/SQL solution you can do something like this:
Modified to handle duplicate CreationDate's
var query = from a in context.AppleGroup
orderby a.CreationDate
select new
{
AppleType = a.AppleType,
CreationDate = a.CreationDate,
OrderIntroduced = (from b in context.AppleGroup
where b.CreationDate < a.CreationDate
select b).Count() + 1
};