I have searched for an answer to my question, but have been unable to find one that meets my needs.
The following two code snippets return the same thing and I have no preference which one to use, I am just including both in case it helps someone answer my question
private List<MyClass> GetMyClass(string name, string city, string state, string zip)
{
using (MyEntities ctx = new MyEntities())
{
var results = from a in ctx.MyEntity
where (a.Name == name &&
a.City == city &&
a.State == state &&
a.ZIP == zip)
select a;
return results.ToList();
}
}
private List<MyClass> GetMyClass(string name, string city, string state, string zip)
{
using (MyEntities ctx = new MyEntities())
{
var results = ctx.MyEntity.Where(a => a.Name == name)
.Where(a => a.City == city)
.Where(a => a.State == state)
.Where(a => a.ZIP == zip)
.Select(a => a);
return results.ToList();
}
}
For the purposes of this example, let's say I have a search screen which requires users to enter a Name and a City; State and ZIP are optional. The query must at least search by those two fields, and any additional fields, if necessary.
Obviously, with my above examples, if a user searches only by Name and City, they would not get any results as the queries would be trying to match State == null and ZIP == null since those two parameters where not supplied.
How can I rewrite this code to only search on the fields that parameters have been supplied for?
You could just chain them, something like:
var results = ctx.MyEntity.AsQueryable();
if(name != null)
results = results.Where(a => a.Name == name);
// ... snip ...
if(zip != null)
results = results.Where(a => a.ZIP == zip)
return results.ToList();
var results = from a in ctx.MyEntity
where ((a.Name == name || name == null) &&
(a.City == city || city == null) &&
(a.State == state || state == null) &&
(a.ZIP == zip) || zip == null)
select a;
Related
I want to do something like this
public string GetSiteTitleFromChangeHistory(int siteId)
{
var changeHistories = changeHistoryRepository.GetAll(c => c.SiteRegistryId == siteId);
var value = changeHistories.firstOrDefault(r=>r.State="Active")
return value.Title;
}
public IQueryable<PendingReconfirmation> GetSitesForBusinessReconfirmationReminder(IList<StateStatus> stateStatusMappingIds,
string country, int reminderDay)
{
return from reg in repositorySpositeRegistry.GetAll(x => x.SiteUrlcountryCode != null
&& x.SiteUrlcountryCode.ToLower() == country.ToLower())
select new PendingReconfirmation()
{
Id = reg.Id,
SiteTitle = GetSiteTitleFromChangeHistory(reg.Id!).ToString() ?? reg.SiteTitle,
};
}
Repository.GetAll look like this
public IQueryable<T> GetAll(Expression<Func<T, bool>>? filter = null)
{
var query = entities.AsQueryable();
if (filter != null)
query = query.Where(filter);
return query;
}
But I am getting error
The client projection contains a reference to a constant expression of '' through the instance method 'GetSiteTitleFromChangeHistory'. This could potentially cause a memory leak; consider making the method static so that it does not capture constant in the instance.
Any help will be highly appreciated
Make this function GetSiteTitleFromChangeHistory as STATIC.
Is there a specific reason you split up GetSiteTitleFromChangeHistory into a separate method?
Otherwise you should be able to do a subquery like so, provided the queryable used for the subquery is based on a dbset in the same efcontext:
public IQueryable<PendingReconfirmation> GetSitesForBusinessReconfirmationReminder(IList<StateStatus> stateStatusMappingIds,
string country, int reminderDay)
{
return from reg in repositorySpositeRegistry.GetAll(x => x.SiteUrlcountryCode != null
&& x.SiteUrlcountryCode.ToLower() == country.ToLower())
select new PendingReconfirmation()
{
Id = reg.Id,
SiteTitle = changeHistoryRepository.GetAll(c => c.SiteRegistryId == reg.Id && c.State == "Active").FirstOrDefault().Title ?? reg.Title
};
}
This question already has answers here:
Linq - check condition in where clause if field can be null
(3 answers)
Closed 4 years ago.
How can I transform the string with the query in it into an actual LINQ expression so I can execute it?
if(email!= null)
{
query += "x => x.Email.Contains(email)";
}
if (firstname != null)
{
query += "&& x.FirstName.Contains(firstname)";
}
if (lastname != null)
{
query += "&& x.LastName.Contains(lastname)";
}
return context.UserAccounts.Where(query).ToList();
Try this:
<your collection>.
.Where(o => (email!= null)? o.Email.Contains(email) : true).
.Where(o => (firstname != null)? o.FirstName.Contains(firstname) : true).
.Where(o => (lastname != null)? o.LastName.Contains(lastname) : true).
ToList();
Basically it means the filter will apply only when the condition is met (just like in your if sentences).
If the query is required with the combination of where clauses then every time result needs to be saved in query itself
var query = context.UserAccounts;
if(email != null)
{
query = query.Where(x => x.Email.Contains(email));
}
if (firstname != null)
{
query = query.Where(x => x.FirstName.Contains(firstname));
}
if (lastname != null))
{
query = query.Where(x => x.LastName.Contains(lastname));
}
return query.ToList();
Another complex approach could be to use Actions
Instead of saving your query as a string you could save it as an IQueryable (from the System.Linq namespace).
var query = context.UserAccounts;
if(email!= null)
{
query = query.Where(x => x.Email.Contains(email));
}
if (firstname != null)
{
query = query.Where(x => x.FirstName.Contains(firstname));
}
if (lastname != null)
{
query = query.Where(x => x.LastName.Contains(lastname));
}
return query.toList();
When you finally call ToList() the IQueryable is enumerated to a List of UserAccount.
Maybe I'm not seeing your problem correctly so excuse me if i'm wrong.
Why convert the string to a LINQ expression when you can do this:
var query = context.UserAccounts;
if(email != null)
{
query = query.Where(x => x.Email.Contains(email));
}
if (firstname != null)
{
query = query.Where(x.FirstName.Contains(firstname));
}
if (lastname != null))
{
query = query.Where(x.LastName.Contains(lastname));
}
return query.toList();
I have to return only the primary contact within an account of a person that is a member, but my query is returning all all members within the organization. I have tried reordering it and using stuff like Single() but with no luck. I need a way to put a where clause that says I only want the Primary Contact with an account.
if ((!string.IsNullOrEmpty(organization)) && (!string.IsNullOrEmpty(city)) && state != null)
{
var corporatemembers = (from a in crmContext.bpt_membertypeSet
where a.bpt_membertypename == "Member (Individual)" || a.bpt_membertypename == "Courtesy"
|| a.bpt_membertypename == "Affiliate" || a.bpt_membertypename == "Member"
select new { a.Id }).ToList();
foreach (var corporatemember in corporatemembers)
{
var directories = (from b in crmContext.AccountSet
join a in crmContext.ContactSet
on b.Id equals a.ParentCustomerId.Id
where a.bpt_MemberTypeId.Id == corporatemember.Id
where a.bpt_memberstatus == (int)bpt_memberstatus.Active
where b.Name.Contains(organization)
where a.Address1_City.Contains(city)
where a.bpt_stateorusterritory.Value == state.Value
select new { b.PrimaryContactId, b.EMailAddress1, a.Address1_City, b.Name, b.WebSiteURL, a.bpt_stateorusterritory }).ToList();
foreach (var directory in directories.ToList().OrderBy(o => o.Name))
{
var cityState = String.Empty;
if (directory.bpt_stateorusterritory != null)
cityState = directory.Address1_City + ", " + Utility.GetOptionSetValueLabel(crmContext, new Microsoft.Xrm.Sdk.Entity(Xrm.Contact.EntityLogicalName), "bpt_stateorusterritory", new Microsoft.Xrm.Sdk.OptionSetValue(directory.bpt_stateorusterritory.Value));
else
cityState = directory.Address1_City;
oMemberList.Add(new Members { FullName = directory.PrimaryContactId, FullNameEmail = directory.EMailAddress1, OrganizationName = directory.Name, OrganizationUrl = directory.WebSiteURL, CityState = cityState });
}
}
}
this code returns all if the search categories are all filled. I have 4 clauses for all scenarios. But at the end of the whole thing I have:
oMembers.ToList()
Thanks
Edit: here is sample data but the output is wrong. There should only be one organization and one contact
I think you are using the wrong field for the join here. This would return all contacts who are a child of that account - which is probably why you are getting multiple results.
on b.Id equals a.ParentCustomerId.Id
The primary contact field on the account is primarycontactid so I suggest you update your query to reference that attribute instead.
I want to return only those data from sql table which contains specific values from list.How can i do that ?
List<decimal> userHeirarchyId = new List<decimal>();
List<decimal> userGroupId = new List<decimal>();
//Get groups based on user
string userGroupIds = (from ucp in db.UserControlPrivileges
where ucp.UserId == (decimal)AMSECSessionData.userId
select ucp.GroupIds).FirstOrDefault().ToString();
userGroupId = userGroupIds.Split(',').Select(x => decimal.Parse(x)).ToList();
//Get heirarchy based on company and usergroup
userHeirarchyId = db.Groups
.Where(x=>x.Hierarchy.CompanyId==(decimal)AMSECSessionData.companyId
=>stuck here && x.GroupId.contains(userGroupIds ))
Any help will be appreciated..
Try this. Change the order how you're using Contains like 'your compare list'.Contains(member name)
var userHeirarchyId = db.Groups
.Where(x=> x.Hierarchy.CompanyId == (decimal)AMSECSessionData.companyId
&& userGroupIds.Contains(x.GroupId))
Write it like this :
var user = db.UserControlPrivileges.FirstOrDefault(u =>
u.UserId == (decimal)AMSECSessionData.userId);
if(user == null || user.GroupIds == null)
{
return;
}
var userIds = user.GroupIds.Split(',').Select(x => decimal.Parse(x)).ToList();
And then :
var userHeirarchyId = db.Groups
.Where(x => x.Hierarchy.CompanyId==(decimal)AMSECSessionData.companyId
&& userIds.Contains(x => x.GroupId));
So i have the query:
var query =
from product in db.LUT_ProductInfos
where product.flavor == flavor && product.Container == container
select flavor;
which is returning 1 record (it should always return one record). How do i pull individual attribute values from the result? For example, if it returns 1 record with 3 columns like firstName lastName phoneNumber, and i want to do something with each of the values like
string fName = firstName
string lName = lastName
int pNumber = phoneNumber
without getting into data mapping for objects, what is the most direct way to extract those values from the result variable query
var query =
from product in db.LUT_ProductInfos
where product.flavor == flavor && product.Container == container
select new {product.Foo, product.flavor.Bar, ...};
var row = query.First(); // or Single(), FirstOrDefault(), SingleOrDefault()
string foo = row.Foo;
int bar = row.Bar;
...
This has the advantage that only the desired properties are included in the SELECT statement, and there are no hidden additional round-trips (lazy loading).
var singleResult =
(from product in db.LUT_ProductInfos
where product.flavor == flavor && product.Container == container
select flavor).Single();
string fName = singleResult.firstName
string lName = singleResult.lastName
int pNumber = singleResult.phoneNumber
var row = db.LUT_ProductInfos
.SingleOrDefault(product => product.flavor == flavor && product.Container == container);
if (row != null)
{
string firstName = row.fName;
string lastName = row.lName;
string phone = row.pNumber;
}
The best and easiest way to do this is to recode like this:
var query =
(from product in db.LUT_ProductInfos
where product.flavor == flavor && product.Container == container
select flavor).FirstOrDefault();
it will return the first matched record. If there's no matched record it will retutn null value, otherwise it returns an object of LUT_ProductInfos class. you can also skip records as you wish like this:
var query =
(from product in db.LUT_ProductInfos
where product.flavor == flavor && product.Container == container
select flavor).Skip(25).FirstOrDefault();