I am using LINQ query to get the rows with certain conditions. Here is the query.
var query = from v in dt1.AsEnumerable()
join c in dt2.AsEnumerable() on v.Field<int>("ID") equals c.Field<int>("ID")
where v.Field<string>("col1").Equals("abcd")
&& (c.Field<string>("col1").Equals("8776") || c.Field<string>("col1").Equals("8775"))
select new
{
ok = (from a in v where v.Field<string>("stah").Equals("1") select a).count(),
ok1 = (from a in v where v.Field<string>("stah").Equals("2") select a).count(),
ok2 = (from a in v where v.Field<string>("stah").Equals("3") select a).count()
};
The error is present in
ok = (from a in v where v.Field<string>("stah").Equals("1") select a).count()
The error is
could not find an implementation of the query pattern for source type
'system.data.DataRow'. 'Where' not found
Sample Input :
dt1
iD col1 stah
1 4567 1
2 8748 2
3 3487 3
4 8776 1
dt2
iD col1
1 4754
2 4576
Output
Get count of all rows where stah=1 && dt2.col1='4754'
But I cannot get it working. What is the correct syntax for this ?
If I have understood you correctly, then this is what you need:-
var query = dt1.AsEnumerable()
.Where(x => x.Field<int>("stah") == 1
&& dt2.AsEnumerable()
.Any(z => z.Field<int>("Id") == x.Field<int>("Id")
&& z.Field<string>("Col1") == "4754")
).Count();
#HarshitShrivastava mentioned that my previous attempt at the query didn't take into account all the where conditions.
How about this version using a mix of Linq query and Linq Lambda:
var query = from dataRows1 in dt1.AsEnumerable().Where(r => r.Field<string>("col1").Equals("abcd"))
join dataRows2 in dt2.AsEnumerable().Where(r => r.Field<string>("col1").Equals("8776") || r.Field<string>("col1").Equals("8775"))
on dataRows1.Field<int>("ID") equals dataRows2.Field<int>("ID") into b
select new
{
id = dataRows1.Field<int>("ID"),
ok = (from a in b where a.Field<string>("stah").Equals("1") select a).Count(),
ok1 = (from a in b where a.Field<string>("stah").Equals("2") select a).Count(),
ok2 = (from a in b where a.Field<string>("stah").Equals("3") select a).Count()
};
Note: I included the ID field in the projected output just for verifying the results. Remove as needed.
Related
I have 3 tables
- ERPEntry
- ERPEntryType
- ERPApp
I am trying to get data from these 3 tables using the below query but i got the error :
specified linq expression contains references to queries that are
associated with different contexts
var erpEntryInfo = (from s in ERPDB.ERPEntrys
JOIN t in ERPDB.ERPEntryTypes
on s.EntryTypeID equals t.EntryTypeID
join a in APPDB.ERPApps
on s.AppId equals a.AppId
where s.UserIDAdded == '250176'
select new ERPInfo
{
EntryId = s.EntryID,
EntryType = t.EntryTypeName,
ERPApp = a.ApplicationName,
DateAdded = s.DateAdded
}).OrderByDescending(d => d.DateAdded).Take(10).ToList();
I searched based on the errror and tried to split the above query into 2 as below.
var res = (from s in ERPDB.ERPEntrys
join t in ERPDB.ERPEntryTypes
on s.EntryTypeID equals t.EntryTypeID
where s.UserIDAdded == '250176'
select new {s.EntryTypeID, s.DateAdded, t.EntryTypeName, s.AppID }).OrderByDescending(d => d.DateAdded).Take(10).ToArray();
var y = (from a in APPDB.ERPApps
join b in res on a.AppId equals //??//
select new ERPInfo
{
EntryId = b.EntryID,
EntryType = b.EntryTypeName,
ERPApp = a.ApplicationName,
DateAdded = b.DateAdded
}).ToList();
I am having an issue in the above query to access AppId which i got into the result res..i commented with //??// in the above code
can i get any help on this.
When querying my entity framework DB, I am trying to match a condition based on the values from 2 rows.
My current query looks like this:
var query = context.table.where(x => x.row > 2);
This all works fine.
What I now want to achieve is to query the table based on the value in current and next row eg:
var query = context.table.where(x => x.row > 2 && x.row[next row up in DB] < 2);
Can this be done.
I know I can achieve this in code, but can it be done in a single query using LINQ and entity?
Here is an example of how I would do this with SQL:
SELECT *
FROM t_Table p
INNER JOIN t_Table f
ON (p.id + 1) = f.id
WHERE p.column = whatever
AND f.column = whatever2
Translating your sample SQL into LINQ to SQL:
var ans = from p in t_table
from f in t_table
where (p.id+1) == f.id && p.column == whatever && f.column == whatever2
select new { p, f };
This does not appear to generate an inner join in SQL but rather a cross-join, but I assume the SQL engine will handle it appropriately. Note that LINQ can only do equi-joins.
I didn't realize you can do (some) expressions in LINQ joins as long as equal is the primary operator, and this generates a sub-select and an inner join, which seems quite a bit faster:
var ans = from p in t_table
where p.column == whatever
let pidplus1 = p.id+1
join f in t_table on pidplus1 equals f.id
where f.column == whatever2
select new { p, f };
I have an EF query which gets products from the database.
var query = (from pPrice in db.ProductPricing
join prod in db.Products on pPrice.ProductID equals prod.ProductID
join productExt in db.ProductsExt on prod.ProductID equals productExt.ProductID into pExts
from prodExt in pExts.DefaultIfEmpty()
where (includeNonPublic || pPrice.ShowOnline == 1)
&& ((eventID.HasValue && pPrice.EventID == eventID) || (!eventID.HasValue && !pPrice.EventID.HasValue))
orderby prod.DisplayOrder
select new ProductPricingInfo()
{
Product = prod,
ProductPricing = pPrice,
ProductExtension = prodExt
});
I have a table where I can specify add-on products (products which can be bought once the parent item has been bought).
My query to fetch these add-on products is
var addOnProductsQuery = (from pa in db.ProductAddons
where pa.EventID == eventID && pa.StatusID == 1
select new { ProductID = pa.ChildProductId });
Now what I am trying to do is filter on the query variable to only return products which are not in the addOnProductsQuery result.
Currently I have
var addOnProducts = addOnProductsQuery.ToList();
query = query.Where(e => !addOnProducts.Contains(e.Product.ProductID));
But there is a syntax error on the Contains(e.Product.ProductID)) statement
Argument 1: cannot convert from int to anonymous type: int ProductID
Chetan is right in the comments, you need to select the integer from the object before using Contains.
You can do it in 2 ways:
First you could just take the integer initially:
var addOnProductsQuery = (from pa in db.ProductAddons
where pa.EventID == eventID && pa.StatusID == 1
select new pa.ChildProductId);
This should give int as type so you can use Contains later with no problem.
Second, if you want to keep the addOnProductsQuery unchanged:
var addOnProducts = addOnProductsQuery.Select(a => a.ProductID).ToList();
query = query.Where(e => !addOnProducts.Contains(e.Product.ProductID));
I have been stuck on this for an embarrassing day... can't seem to convert this to linq. My issue also is that Attendee can be null.
select c.activityId, count(distinct b.attendeeId)
from Attendee a, sponsor_activity c
left outer join sponsor_attendance b
on c.ActivityId = b.ActivityId
where a.RegistrationId = 62
AND c.SponsorLevelId = 2
group by c.activityId
So far I have this code... but I am not getting distinct values
var activity_count = (from c in db.Sponsor_Activitys
where c.SponsorLevelId == pledgelvl
from a in db.Attendees.DefaultIfEmpty()
where a.RegistrationId == registration
select new { Activityid = c.ActivityId, NumAttending = db.Sponsor_Attendances.Count(x => x.ActivityId == c.ActivityId) })
.ToList();
Sponsor_Attendance
AttendanceId
AttendeeId
ActivityId
Sponsor_Activity
ActivityId
SponsorLevelId
Attendee
AttendeeId
RegistrationId
Returns:
## ActivityID ## ## NumAttending ##
2 4
3 0
4 2
2 4
3 0
4 2
2 4
3 0
4 2
Currently there are 3 attendees that have a registrationid that matches... so this is why it is repeated 3 times in the output.
First, it helps if your original queries are readable. :)
Query:
SELECT c.activityId
, COUNT(DISTINCT b.attendeeId)
FROM Attendee a
, sponsor_activity c
LEFT OUTER JOIN sponsor_attendance b
ON c.ActivityId = b.ActivityId
WHERE a.RegistrationId = 62 AND
c.SponsorLevelId = 2
GROUP BY c.activityId;
Linq:
var activity_count = (from activity in db.Sponsor_Activitys
where activity.SponsorLevelId == pledgelvl
from attendee in db.Attendees.DefaultIfEmpty()
where attendee.RegistrationId == registration
select new
{
Activityid = activity.ActivityId,
NumAttending = db.Sponsor_Attendances.Count(x => x.ActivityId == activity.ActivityId)
}).ToList();
My answer:
var query = from activity in db.Sponsor_Activitys
// Left outer join onto sponsor_attendances
join attendance in db.Sponsor_Attendances
on activity.ActivityId equals attendance.ActivityId into g
from q in g.DefaultIfEmpty()
join attendee in db.Attendees
on q.AttendeeId equals attendee.AttendeeId
where attendee.RegistrationId == registration &&
activity.SponsorLevelId == pledgelvl
select new
{
Activityid = activity.ActivityId,
NumAttending = db.Sponsor_Attendances.Count(x => x.ActivityId == activity.ActivityId)
}
Given the cartesian join (typically bad!), this might be a better example on just executing SQL rather than trying to convert to Linq.
Sorry to bother you, however I'm having issues converting my SQL Query into C# Entity Framework.
My SQL query is as follows:
SELECT CAST(ROUND(sum(size/rate), 0) AS INT) s,
CAST(ROUND(sum(PL/rate), 0) AS INT) PL
FROM [bs].[b] b
join [bs].[s] s on b.id = s.b_id
join [bs].[o] o on s.o_id = o.id
join [bs].[a] a on o.a_id = a.id
join [fs].[f] f on b.f_id = f.id
where f.r_date
between '2013-05-01 00:00:00.000'
and '2013-05-31 00:00:00.000'
and s.deleted_at is NULL
and b.group_id = '0'
and (o.a_id = 50 or o.a_id = 52)
I have in turn managed to get all the joins done and where statement in place (a.k.a. 'The Easy Bit') however I just cannot find a way to get those sums for the column totals to work.
This is what I have in place so far:
var GroupSk = (from Bs in sb.b
join S in sb.s on Bs.id equals S.b_id
join O in sb.o on S.o_id equals O.id
join A in sb.a on O.a_id equals A.id
join Fs in sb.vw_f on Bs.f_id equals Fs.f_id
where Fs.r_date >= t_FromDate && Fs.r_date <= t_ToDate
where S.deleted_at == null
where Bs.group_id == 0
where O.a_id == 50 || O.a_id == 52
select new {
As you can see, it's everything up until the SUM part of the query.
This query can return anywhere from 1-150000 rows, and I need a way to ensure that the column totals I get back are returned in a timely manner.
I had originally planned on using a ForEach loop but had trouble implementing it (along with the fact that it'll probably take a LONG time if a larger number of rows are returned).
I'm aware there are a few 'sum column total' questions out there, however they don't deal with multiple tables and multiple column outputs. They also appear to be limited to 2 or 3 columns total, whereas my tables far exceed that.
Any & all help would be greatly appreciated.
It's a bit of a hack, but it works. The trick is to make one group containing all items and then do the sums over the group:
var GroupSk = (from Bs in sb.b
join S in sb.s on Bs.id equals S.b_id
join O in sb.o on S.o_id equals O.id
join A in sb.a on O.a_id equals A.id
join Fs in sb.vw_f on Bs.f_id equals Fs.f_id
where Fs.r_date >= t_FromDate && Fs.r_date <= t_ToDate
where S.deleted_at == null
where Bs.group_id == 0
where O.a_id == 50 || O.a_id == 52
select new { r1 = ??.size / ??.rate, r2 = ??.PL / ??.rate })
.GroupBy(x => 0)
.Select(g => new {
R1 = g.Sum(x => x.r1),
R2 = g.Sum(x => x.r2)
});
I put ?? marks where I didn't know the origin of the properties, so you'll have to substitute the right variable names there. (Bs, S, O, A, Fs).
This will translate into one SQL query, so all the processing is done by the database engine and only the small result object is transferred over the wire.