I have tried to make the following sql in linq with no luck can some help mw with this?
select * from customer c
where companynumber = 1
and status <> 0
and lastdate = (select max(lastdate) from customer where customernumber = c.customernumber)
Gives 22 records
My best try was this:
_ctx.Customers
.Where(r => r.CompanyNumber == companyNumber && r.CustomerNumber != null && r.Status != 0)
.GroupBy(c => c.CustomerNumber)
.Select(g => new
{
name = g.Key,
count = g.Count(),
date = g.Max(x => x.LastEdited)
})
.OrderBy(c => c.name);
Gives 22.000+ records
But not the result as the above SQL
UPDATE:
The following LINQ does the trick ;o)
from a in _ctx.Customers
where a.CustomerNumber != null && a.CompanyNumber == companyNumber
group a by new { a.CustomerNumber } into g
select g.OrderByDescending(a => a.LastEdited).FirstOrDefault() into c
where c.Status == 1
select c
I had to move the where c.Status == 1 into my first select statment
Related
I have a SQL query need to do in LINQ. Can anyone helps in converting?
SELECT *
FROM profile
WHERE ProfileId <> 1221 AND IsActive = 1 AND
ProfileId NOT IN (SELECT ReportingPerson
FROM ReportingPersons
WHERE Employee = 1221)
var reportingPerson = context.ReportingPersons.Where(x =>
x.Employee == 1221)
.Select(c => c.ReportingPerson
).ToList();
var result = context.Profiles
.Where(x =>
x.ProfileId != 1221 &&
x.IsActive &&
!reportingPerson.Contains(x.ProfileId)
.ToList();
select count(distinct LicencePlate) from MT_Vehicle where IsDeleted=0 and CreatedBy = 1
var count = MT_Vehicle.Where(x => x.IsDeleted==0 && x.CreatedBy == 1)
.Select(x => x.LicencePlate)
.Distinct()
.Count();
You can write that as:
var count = db.MT_Vehicle
.Where( v => v.IsDeleted == 0 && v.CreatedBy == 1 )
.Select(v => v.LicencePlate)
.Distinct()
.Count();
I am having following query & i need to write it in linq. I am stuck in NOT IN part.
SELECT A.CODE,
A.DATETIME,
A.DATE
FROM TABLE_IO A
WHERE A.DATE>= '01/06/2015' AND A.DATE<='01/06/2015'
AND A.CODE NOT IN(
SELECT CODE
FROM TABLE_ENTRY B
WHERE A.CODE=B.CODE AND A.DATE=B.ENTRY_DATE AND METHOD='M'
)
How to write NOT IN part?
var data = ctx.TABLE_IO.Where(m=>m.Date >= '01/06/2015' && m.Date <= '01/06/2015')
.Select(m=>m).ToList();
You can use !Any:
DateTime dateToCompare = new DateTime(2015, 6, 1);
var data = ctx.TABLE_IO
.Where(m => m.Date >= dateToCompare && m.Date <= dateToCompare)
.Where(m => !ctx.TABLE_ENTRY
.Any(te => m.Code == te.Code && m.Date == te.ENTRY_DATE && te.METHOD == "M"))
.ToList();
I would prefer this, i'm fairly sure that it will be translated to a performant NOT EXISTS which has also no issues with null values like NOT IN/Contains.
The direct translation of NOT IN/Contains would be this:
var data = ctx.TABLE_IO
.Where(m => m.Date >= dateToCompare && m.Date <= dateToCompare)
.Where(m => !ctx.TABLE_ENTRY.Select(te => te.Code).Contains(m.Code))
.ToList();
Basically you can do something such as (pseudo queries below)
var exclusions = table_B.Where(b => [exclusion condition] ).Select(b => b.Id)
var data = ctx.TABLE_IO.Where(m => !exclusions.Contains(m.Id))
select c.Name, d.First_Name, COUNT(c.Name) as qty
from order_product_s a
inner join Order_s b on a.Order_Id = b.Id
inner join Product_s c on a.Product_Id = c.Id
inner join Customer_s d on b.Customer_Id = d.Id
where b.Customer_Id = 4869
group by c.Name, d.First_Name
Something like this:
int __UserId = 4869;
var results =
(
from t in
(
from a in Repo.order_product_s
from b in Repo.Order_s
.Where(bb=> bb.id == a.Order_Id)
from c in Repo.Product_s
.Where(cc => cc.Id == a.Product_Id)
from d in Repo.Customer_s
.Where(dd => dd.Id == b.Customer_Id)
where b.Customer_Id == __UserId
select new
{
Name = c.Name
,First_Name = d.First_Name
}
)
group t by new { t.Name , t.First_Name } into g
select new
{
Name = g.Key.Name
,First_Name=g.Key.First_Name
,qty = g.Count( x => x.Name != null)
}
).ToList();
or more compact:
var results =
(
from a in Repo.order_product_s
from b in Repo.Order_s
.Where(bb=> bb.id == a.Order_Id)
// .DefaultIfEmpty() // <== makes join left join
from c in Repo.Product_s
.Where(cc => cc.Id == a.Product_Id)
// .DefaultIfEmpty() // <== makes join left join
from d in Repo.Customer_s
.Where(dd => dd.Id == b.Customer_Id)
// .DefaultIfEmpty() // <== makes join left join
where b.Customer_Id == __UserId
select new
{
Name = c.Name
,First_Name = d.First_Name
}
into t group t by new { t.Name , t.First_Name } into g
select new
{
Name = g.Key.Name
,First_Name=g.Key.First_Name
,qty = g.Count( x => x.Name != null)
// Or like this
// ,qty = g.Select(x => x.Name).Where(x => x != null).Count()
// and if you ever need count(distinct fieldname)
//,qty = g.Select(x => x.GroupName).Where(x => x != null).Distinct().Count()
}
)
// .OrderBy(t => t.Name).ThenBy(t => t.First_Name).ThenBy(t => t.qty) // Order in SQL
.ToList()
// .OrderBy(t => t.Name).ThenBy(t => t.First_Name).ThenBy(t => t.qty) // Order in .NET
;
I have a successful query that links two tables with a where and orderby clause, but I wanted to add to just select specific columns instead of getting everything back.
PART 1
When I attempt this I get syntax errors on the orderby line, if I remove the orderby line the syntax errors move to the where line.
Error 3 Cannot implicitly convert type 'System.Linq.IOrderedQueryable' to 'System.Linq.IQueryable'. An explicit conversion exists (are you missing a cast?)
IQueryable<VendorProfile> query = _db.VendorProfiles
.Include("VendorCategories")
.Include("VendorsSelected")
.Select(s => new { s.ProfileID, s.Name, s.CompanyName, s.City, s.State, s.DateCreated, s.VendorsSelected, s.VendorCategories })
.Where(x => x.VendorsSelected.Select(s => s.UserName).Contains(HttpContext.Current.User.Identity.Name))
.OrderBy(x => x.DateCreated);
if (criteria.name != string.Empty)
query = query.Where(v => v.Name.Contains(criteria.name));
if (criteria.company != string.Empty)
query = query.Where(v => v.CompanyName.Contains(criteria.company));
if (criteria.startDate != null && criteria.endDate != null)
query = query.Where(v => v.DateCreated > criteria.startDate && v.DateCreated < criteria.endDate);
if (criteria.categories != null && !criteria.categoryMatchAll)
query = query.Where(v => criteria.categories.AsQueryable().Any(cat => v.VendorCategories.Select(vendCat => vendCat.CategoryID).Contains(cat)));
if (criteria.categories != null && criteria.categoryMatchAll)
query = query.Where(v => criteria.categories.AsQueryable().All(cat => v.VendorCategories.Select(vendCat => vendCat.CategoryID).Contains(cat)));
if (criteria.minorityType != null)
query = query.Where(v => v.MinotiryOwned == criteria.minorityType);
if (criteria.diversityClass != null)
query = query.Where(v => v.DiversityClassification == criteria.diversityClass);
return query.ToList();
PART 2
I also wanted to know if I could extract the selected columns into a view model class, so I tired this and I get same results as above on the orderby line
Error 4 Cannot implicitly convert type 'System.Linq.IOrderedQueryable' to 'System.Linq.IQueryable'. An explicit conversion exists (are you missing a cast?)
ANSWER
I think you helped me stumble upon the fact that the types don't match. Making the IQueryable type and the select new type and the return type the SAME makes the syntax happy. Using var does not like.
public IEnumerable<BrowseVendorModel> SearchVendors(CustomSearchModel criteria)
{
IQueryable<BrowseVendorModel> query = _db.VendorProfiles
.Include("VendorCategories")
.Include("VendorsSelected")
.Select(s => new BrowseVendorModel
{
ProfileID = s.ProfileID,
Name = s.Name,
CompanyName = s.CompanyName,
City = s.City,
State = s.State,
DateCreated = s.DateCreated,
VendorsSelected = s.VendorsSelected,
VendorCategories = s.VendorCategories
})
.Where(x => x.VendorsSelected.Select(s => s.UserName).Contains(HttpContext.Current.User.Identity.Name))
.OrderBy(x => x.DateCreated);
if (criteria.name != string.Empty)
query = query.Where(v => v.Name.Contains(criteria.name));
if (criteria.company != string.Empty)
query = query.Where(v => v.CompanyName.Contains(criteria.company));
if (criteria.startDate != null && criteria.endDate != null)
query = query.Where(v => v.DateCreated > criteria.startDate && v.DateCreated < criteria.endDate);
if (criteria.categories != null && !criteria.categoryMatchAll)
query = query.Where(v => criteria.categories.AsQueryable().Any(cat => v.VendorCategories.Select(vendCat => vendCat.CategoryID).Contains(cat)));
if (criteria.categories != null && criteria.categoryMatchAll)
query = query.Where(v => criteria.categories.AsQueryable().All(cat => v.VendorCategories.Select(vendCat => vendCat.CategoryID).Contains(cat)));
if (criteria.minorityType != null)
query = query.Where(v => v.MinotiryOwned == criteria.minorityType);
if (criteria.diversityClass != null)
query = query.Where(v => v.DiversityClassification == criteria.diversityClass);
return query;
}
The first example requires var because you are changing the shape of the query by projecting into anonymous type. The second example can either use var or IQueryable<VendorProfileViewModel> because you are changing the shape of the query by projecting into VendorProfileViewModel.