Linq AND searches - c#

I have a array called searchWords, that is a dynamic array that stores peoples search words. I need to add an option for AND search. So the search will only retrieve items if both variables in searchWords contains for resultList. Now it is searchWords.Any. Will searchWords.All make this works?
var resultList = from c in context.Category
join q in context.Question on c.CategoryId equals q.CategoryId
join qf in context.QuestionFilter on q.QuestionId equals qf.QuestionId
join a in context.Answer on q.QuestionId equals a.QuestionId into QuestAnsw
from a2 in QuestAnsw.DefaultIfEmpty()
orderby c.SortOrder
orderby q.SortOrder
where qf.FilterId == filterKeyAsInt
&& q.Published == true
&& c.Published == true
&& q.CustomerId == customerId
&& (searchWords.Any(w => a2.Text.Contains(w))
|| searchWords.Any(w => c.Text.Contains(w))
|| searchWords.Any(w => q.Text.Contains(w)))
select new { Category = c, Question = q };

You can put multiple clauses inside an All(), e.g.
&& (searchWords.All(w =>
a2.Text.Contains(w) &&
c.Text.Contains(w) &&
q.Text.Contains(w)))
...

You can do this if use searchWords.All, but i think searchWords.Any is more intuitive.
var resultList = from c in context.Category
join q in context.Question on c.CategoryId equals q.CategoryId
join qf in context.QuestionFilter on q.QuestionId equals qf.QuestionId
join a in context.Answer on q.QuestionId equals a.QuestionId into QuestAnsw
from a2 in QuestAnsw.DefaultIfEmpty()
orderby c.SortOrder
orderby q.SortOrder
where qf.FilterId == filterKeyAsInt
&& q.Published == true
&& c.Published == true
&& q.CustomerId == customerId
&& !
(
searchWords.All(w => !a2.Text.Contains(w))
&& searchWords.All(w => !c.Text.Contains(w))
&& searchWords.All(w => !q.Text.Contains(w))
)
select new { Category = c, Question = q };

Related

LINQ where clause is being ignored

I am have an issue with a linq query. I am joining two tables but the where clauses are being completely ignored.
using (var db = new Context())
{
var count = (from c in db.PERSON
join dt in db.DATA_INPUT_CHANGE_LOG
on c.DataInputTypeId equals dt.DataInputTypeId
join x in db.DATA_INPUT_CHANGE_LOG
on c.Id equals x.DataItemId
where c.PersonId == p1Id &&
c.RefPersonId == p2Id &&
c.RelationshipId == rId
where x.Approved
where x.Checked
where x.Hidden == false
select c).Count();
return count > 0;
}
In this particular query the x.Approved, x.Checked and x.Hidden == false where clauses are completely ignored.
Can anyone point me in the right direction?
Your syntax is incorrect. You should only have one where clause. See below:
var count = (from c in db.PERSON
join dt in db.DATA_INPUT_CHANGE_LOG
on c.DataInputTypeId equals dt.DataInputTypeId
join x in db.DATA_INPUT_CHANGE_LOG
on c.Id equals x.DataItemId
where c.PersonId == p1Id &&
c.RefPersonId == p2Id &&
c.RelationshipId == rId &&
x.Approved &&
x.Checked &&
x.Hidden == false
select c).Count();
return count > 0;

How to Select new model list after GroupBy mothod in Linq?

I want select grouped rows to a new model list.this is my code:
List<Model_Bulk> q = (from a in db.Advertises
join c in db.Companies on a.AdvertiseCompanyID equals c.CompanyID
where a.AdvertiseActive == true
&& a.AdvertiseExpireDate.HasValue
&& a.AdvertiseExpireDate.Value > DateTime.Now
&& (a.AdvertiseObjectType == 1
|| a.AdvertiseObjectType == 2)
select c)
.GroupBy(a => a.CompanyID).Select(a => new Model_Bulk
{
CompanyEmail = a.CompanyContactInfo.Email,
CompanyID = a.CompanyID,
CompanyName = a.CompanyName,
Mobile = a.CompanyContactInfo.Cell,
UserEmail = a.User1.Email,
categories = a.ComapnyCategories
}).ToList();
After group by, i can not use Select and naturally this syntax error raised:
System.Linq.IGrouping' does not contain a definition for 'CompanyContactInfo' and no extension method 'CompanyContactInfo' accepting a first argument of type
System.Linq.IGrouping' could be found (are you missing a using directive or an assembly reference?)
If i try with SelectMany() method.but the result will repeated and groupby method not work properly:
List<Model_Bulk> q = (from a in db.Advertises
join c in db.Companies on a.AdvertiseCompanyID equals c.CompanyID
where a.AdvertiseActive == true
&& a.AdvertiseExpireDate.HasValue
&& a.AdvertiseExpireDate.Value > DateTime.Now
&& (a.AdvertiseObjectType == 1
|| a.AdvertiseObjectType == 2)
select c)
.GroupBy(a => a.CompanyID).SelectMany(a => a).Select(a => new Model_Bulk
{
CompanyEmail = a.CompanyContactInfo.Email,
CompanyID = a.CompanyID,
CompanyName = a.CompanyName,
Mobile = a.CompanyContactInfo.Cell,
UserEmail = a.User1.Email,
categories = a.ComapnyCategories
}).ToList();
Instead of .SelectMany(a => a) you can use .Select(g => g.First()).That will give you the first item of each group.
(from a in db.Advertises
join c in db.Companies on a.AdvertiseCompanyID equals c.CompanyID
where a.AdvertiseActive == true && a.AdvertiseExpireDate.HasValue && a.AdvertiseExpireDate.Value > DateTime.Now && (a.AdvertiseObjectType == 1 || a.AdvertiseObjectType == 2)
select c)
.GroupBy(a => a.CompanyID)
.Select(g => g.First())
.Select(a => new Model_Bulk
{
CompanyEmail = a.CompanyContactInfo.Email,
CompanyID = a.CompanyID,
CompanyName = a.CompanyName,
Mobile = a.CompanyContactInfo.Cell,
UserEmail = a.User1.Email,
categories = a.ComapnyCategories
}).ToList();
Note that this might not be supported, if that is the case add an AsEnumerable call before .Select(g => g.First())
You should understand that after you do GroupBy() in your LinQ expresstion you work with a group so in your example it will be good to write like this:
List<Model_Bulk> q =
(from a in db.Advertises join c in db.Companies on a.AdvertiseCompanyID equals c.CompanyID
where a.AdvertiseActive == true
&& a.AdvertiseExpireDate.HasValue
&& a.AdvertiseExpireDate.Value > DateTime.Now
&& (a.AdvertiseObjectType == 1 || a.AdvertiseObjectType == 2)
select c)
.GroupBy(a => a.CompanyID)
.Select(a => new Model_Bulk
{
CompanyEmail = a.First().CompanyContactInfo.Email,
CompanyID = a.Key, //Note this line, it's can be happened becouse of GroupBy()
CompanyName = a.First().CompanyName,
Mobile = a.First().CompanyContactInfo.Cell,
UserEmail = a.First().User1.Email,
categories = a.First().ComapnyCategories
}).ToList();
Instead you could try something like this, instead of mixing query expressions and methods... (using FirstOrDefault() in the where / select as necessary)
(from a in db.Advertises
join c in db.Companies on a.AdvertiseCompanyID equals c.CompanyID
group a by new { a.CompanyId } into resultsSet
where resultsSet.AdvertiseActive == true && resultsSet.AdvertiseExpireDate.HasValue && resultsSet.AdvertiseExpireDate.Value > DateTime.Now && (resultsSet.AdvertiseObjectType == 1 || resultsSet.AdvertiseObjectType == 2)
select new Model_Bulk
{
CompanyEmail = resultsSet.CompanyContactInfo.Email,
CompanyID = resultsSet.CompanyID,
CompanyName = resultsSet.CompanyName,
Mobile = resultsSet.CompanyContactInfo.Cell,
UserEmail = resultsSet.User1.Email,
categories = resultsSet.ComapnyCategories
}).ToList();

How to Use Data Inside Var in Linq?

I want to sum records using Group by from the all data inside "result view".
can anyone guide me for this.!
Here is My Code
var tData1 = (from i in _data.Transactions
join y in _data.DeviceInformations on i.DeviceInfoId equals y.DeviceInfoId
join u in _data.AccountDevices on y.DeviceInfoId equals u.DeviceInfoId
where y.Active == true && u.AccountId == 1000001 && u.Active == true
group i by i.DeviceInfoId into g
select g.OrderByDescending(t => t.DateCreated)).ToList();
foreach (var xCo in tData1)
{
//I am getting Data in xCo
}
Based on #Nayeem Mansoori solution you can try this.
var tData1 = (from i in _data.Transactions
join y in _data.DeviceInformations on i.DeviceInfoId equals y.DeviceInfoId
join u in _data.AccountDevices on y.DeviceInfoId equals u.DeviceInfoId
where y.Active == true && u.AccountId == 1000001 && u.Active == true
group i by i.DeviceInfoId into g
select new {Id = DeviceInfoId, sum = g.Sum(x=>x.DeviceInfoId)};

why does LINQ To SQL result in SQL like this?

When LINQ translates the below syntax to SQL, the (inner) where clause gets moved to the outer-most query. That's super-unfriendly to the database. I wrote this like Hibernate's HQL (is this appropriate?), and I've written SQL for many moons.
Can anyone help explain what gives, or point me in the way of a resolution?
var rc = (
from dv in (
from dv_j in (
from x in adc.JobManagement
join j in adc.Job on x.JobId equals j.JobId
join js in adc.JobStatus on j.StatusId equals js.JobStatusId
join cm in adc.ClientManagement on j.ClientId equals cm.ClientId
join o in adc.User on cm.UserId equals o.UserId
join jm in adc.JobManagement on j.JobId equals jm.JobId
where
(x.UserId == aid || cm.UserId == aid)
&& (j.StatusDate == null || j.StatusDate >= getFromDate())
&& (jm.ManagementRoleCode == MR_MANAGER)
select new
{
j.JobId,
Job = j.InternalName == null ? j.ExternalName : j.InternalName,
JobStatusDate = j.StatusDate,
JobStatus = js.Code,
Owner = o.Username,
Role = jm.ManagementRoleCode
})
join s in adc.Submission on dv_j.JobId equals s.JobId into dv_s
from s in dv_s.DefaultIfEmpty()
select new
{
dv_j.JobId,
dv_j.Job,
dv_j.JobStatusDate,
dv_j.JobStatus,
dv_j.Owner,
dv_j.Role,
s.SubmissionId,
s.CandidateId,
s.SubmissionDate,
StatusDate = s.StatusDate,
StatusId = s.StatusId
})
join c in adc.Candidate on dv.CandidateId equals c.CandidateId into dv_c
join ss in adc.SubmissionStatus on dv.StatusId equals ss.SubmissionStatusId into dv_ss
from c in dv_c.DefaultIfEmpty()
from ss in dv_ss.DefaultIfEmpty()
orderby
dv.StatusId == null ? dv.StatusDate : dv.JobStatusDate descending,
dv.Job,
c.LastName,
c.NickName,
c.FirstName
select new Projects
{
Id = dv.JobId,
Project = dv.Job,
Submitted = dv.SubmissionDate,
Candidate = FormatIndividual(c.LastName, c.FirstName, c.NickName),
Status = dv.StatusId == null ? ss.Code : dv.JobStatus,
StatusDate = dv.StatusId == null ? dv.StatusDate : dv.JobStatusDate,
Role = dv.Role,
Owner = dv.Owner
});
Try breaking down the one statement into two. This would work as it cannot move the where to a place that doesn't exist yet. This does make multiple round trips to the database, but it is better than having most of several large tables being joined then culled. I would try this:
var inMemoryTable = (
from x in adc.JobManagement
join j in adc.Job on x.JobId equals j.JobId
join js in adc.JobStatus on j.StatusId equals js.JobStatusId
join cm in adc.ClientManagement on j.ClientId equals cm.ClientId
join o in adc.User on cm.UserId equals o.UserId
join jm in adc.JobManagement on j.JobId equals jm.JobId
where
(x.UserId == aid || cm.UserId == aid)
&& (j.StatusDate == null || j.StatusDate >= getFromDate())
&& (jm.ManagementRoleCode == MR_MANAGER)
select new
{
j.JobId,
Job = j.InternalName == null ? j.ExternalName : j.InternalName,
JobStatusDate = j.StatusDate,
JobStatus = js.Code,
Owner = o.Username,
Role = jm.ManagementRoleCode
});
var rc = (
from dv in (
from dv_j in inMemoryTable
join s in adc.Submission on dv_j.JobId equals s.JobId into dv_s
from s in dv_s.DefaultIfEmpty()
select new
{
dv_j.JobId,
dv_j.Job,
dv_j.JobStatusDate,
dv_j.JobStatus,
dv_j.Owner,
dv_j.Role,
s.SubmissionId,
s.CandidateId,
s.SubmissionDate,
StatusDate = s.StatusDate,
StatusId = s.StatusId
})
join c in adc.Candidate on dv.CandidateId equals c.CandidateId into dv_c
join ss in adc.SubmissionStatus on dv.StatusId equals ss.SubmissionStatusId into dv_ss
from c in dv_c.DefaultIfEmpty()
from ss in dv_ss.DefaultIfEmpty()
orderby
dv.StatusId == null ? dv.StatusDate : dv.JobStatusDate descending,
dv.Job,
c.LastName,
c.NickName,
c.FirstName
select new Projects
{
Id = dv.JobId,
Project = dv.Job,
Submitted = dv.SubmissionDate,
Candidate = FormatIndividual(c.LastName, c.FirstName, c.NickName),
Status = dv.StatusId == null ? ss.Code : dv.JobStatus,
StatusDate = dv.StatusId == null ? dv.StatusDate : dv.JobStatusDate,
Role = dv.Role,
Owner = dv.Owner
});

Only parameterless constructors and initializers are supported in LINQ to Entities

While trying a sem-complex query to display some ListView content on the page I got stuck on the famous "Only parameterless contstructor and initializers are supported in LINQ to Entities" error.
Here is the code I used ... I can't find a place where I initialized something inside the query with parameters ....
protected void ArtistsList()
{
Guid cat1 = new Guid("916ec8ae-8336-43b1-87c0-8536b2676560");
Guid cat2 = new Guid("92f2a07f-0570-4521-870a-bf898d1e92d6");
var memberOrders = (from o in DataContext.OrderSet
where o.Status == 1 || o.Status == 0
select o.ID);
var memberOrderDetails = (from o in DataContext.OrderDetailSet
where memberOrders.Any(f => f == o.Order.ID)
select o.Product.ID );
var inventoryItems = (from i in DataContext.InventoryItemSet
select i.Inventory.Product.ID);
var products = (from p in DataContext.ProductSet
join m in DataContext.ContactSet on p.ManufacturerID equals m.ID
where p.Active == true
&& p.ShowOnWebSite == true
&& p.Category.ID != cat1
&& p.Category.ID != cat2
&& p.AvailableDate <= DateTime.Today
&& (p.DiscontinuationDate == null || p.DiscontinuationDate >= DateTime.Today)
&& memberOrderDetails.Any(f => f != p.ID)
&& inventoryItems.Any(f => f == p.ID)
select new { ContactID = m.ID, ContactName = m.Name });
artistsRepeater.DataSource = products;
artistsRepeater.DataBind();
Response.Write("PRODUCT COUNT: " + products.Count());
}
The error itself pops on the line artistsRepeater.DataSource = products;
I tried to comment the lines && memberOrderDetails.Any(f => f != p.ID) and && inventoryItems.Any(f => f == p.ID) , still doesn't change anything
Any hints ?
[edit]
With LINQpad, it works with the join but with it is bugging on the commented line
(from p in Products
join m in Members on p.ManufacturerID.Value equals m.ID
where p.Active == true
&& p.ShowOnWebSite == true
&& p.AvailableDate <= DateTime.Today
&& (p.DiscontinuationDate == null || p.DiscontinuationDate >= DateTime.Today)
//&& (from od in MemberOrderDetails where (from mo in MemberOrders where mo.Status == 1 || mo.Status == 0 select mo.ID).Any(f => f == od.ID) select od.Product.ID)
&& (from inv in InventoryItems select inv.Inventory.ProductID).Any(i => i.Value == p.ID)
select m).Distinct()
[edit-2]
It seems that this query in LINQpad is ok :
(from p in Products
join m in Members on p.ManufacturerID.Value equals m.ID
where p.Active == true
&& p.ShowOnWebSite == true
&& p.AvailableDate <= DateTime.Today
&& (p.DiscontinuationDate == null || p.DiscontinuationDate >= DateTime.Today)
&& !(from od in MemberOrderDetails where (from mo in MemberOrders where mo.Status == 1 || mo.Status == 0 select mo).Any(f => f.ID == od.ID) select od.Product.ID).Any(i => i == p.ID)
&& (from inv in InventoryItems select inv.Inventory.ProductID).Any(i => i.Value == p.ID)
select m)
OK, this is subtle, but what if you change your LINQPad query from:
(from p in Products
join m in Members
on p.ManufacturerID.Value equals m.ID
where p.Active == true
&& p.ShowOnWebSite == true
&& p.AvailableDate <= DateTime.Today
&& (p.DiscontinuationDate == null || p.DiscontinuationDate >= DateTime.Today)
&& (from od in MemberOrderDetails
where (from mo in MemberOrders
where mo.Status == 1 || mo.Status == 0
select mo.ID).Any(f => f == od.ID)
select od.Product.ID)
&& (from inv in InventoryItems
select inv.Inventory.ProductID).Any(i => i.Value == p.ID)
...to:
(from p in Products
join m in Members
on p.ManufacturerID.Value equals m.ID
where p.Active == true
&& p.ShowOnWebSite == true
&& p.AvailableDate <= DateTime.Today
&& (p.DiscontinuationDate == null || p.DiscontinuationDate >= DateTime.Today)
&& (from od in MemberOrderDetails
where (from mo in MemberOrders
where mo.Status == 1 || mo.Status == 0
select mo).Any(f => f.ID == od.ID) // NOTE!
select od.Product.ID)
&& (from inv in InventoryItems
select inv.Inventory.ProductID).Any(i => i.Value == p.ID)
Why? I think type inference might be doing you wrong here. I've seen a similar thing with DateTimes.
The most likely culprit is:
select new { ContactID = m.ID, ContactName = m.Name }
This is because anonymous types do not have parameterless constructors. What's odd about that is that anonymous types are de riguer in LINQ to Entities. I just don't see any other line that could be offending.
First try removing that line and see if the error goes away. At least we'll know if it's that line or not. Then we can focus on figuring out why.
Edit: What are the types of OrderSet.ID, Product.ID and Order.ID and ContactSet.ID? Are any of them Guid and implicitly the Guid constructor is being called?
Convert to a list first, then call your select statement:
var res = abc.getEmployess().toList().select(x => new keyvaluepair<int, string>(x.EmpID, x.EmpName.tostring)).tolist();

Categories

Resources