I have two linq queries, in the second query i use the first query as a sub query. Basically the first query does a groupby to return distinct rows of ContactID to use in the second query, which then does a groupby on idnumber to check for duplicates.
private IQueryable<Contact> GetDistinctContact()
{
IQueryable<Contact> query = (from contact in context.Contacts
where contact.EDITED.Equals(0)
&& contact.NOTACTIVE.Equals(false)
&& contact.ID > 10001
join client in context.Clients on new { ClientID = contact.ID, EDITED = 0, DELETED = false }
equals new { ClientID = client.ContactID, EDITED = client.EDITED, DELETED = client.DELETED }
join member in context.Members on new { MemberID = client.ID, EDITED = 0, DELETED = false }
equals new { MemberID = member.ClientID, EDITED = member.EDITED, DELETED = member.DELETED }
select contact);
return query.GroupBy(x => x.ID).Select(grp => grp.FirstOrDefault());
}
IQueryable<ContactDetailsViewModelPart> query = (from contact in GetDistinctContact()
where contact.IdNumber != null
&& !contact.IdNumber.Trim().Equals("")
&& contact.EDITED.Equals(0)
&& contact.NOTACTIVE.Equals(false)
&& contact.ID > 10001
group contact
by new ContactDetailsViewModelPart
{
IDNumber = contact.IdNumber,
LastName = contact.LastName
}
into idNumberGroup
where idNumberGroup.Count() > 1
select new ContactDetailsViewModelPart
{
IDNumber = idNumberGroup.Key.IDNumber,
LastName = idNumberGroup.Key.LastName
});
return query.ToList();
This is the error i get. I am using Firebird database.
Dynamic SQL Error
SQL error code = -104
Token unknown - line 19, column 9
APPLY
EF generates SQL with a cross apply on sub query. I know this is not supported in later versions of Firebird. Any alternatives to this?
I think the first query could be eliminated (I guess contact.ID is a primary key), and use something like this:
var query =
from contact in context.Contacts
where contact.IdNumber != null
&& !contact.IdNumber.Trim().Equals("")
&& contact.EDITED.Equals(0)
&& contact.NOTACTIVE.Equals(false)
&& contact.ID > 10001
&& context.Clients.Any(client =>
client.ContactID == contact.ID && client.EDITED == contact.EDITED && client.DELETED == contact.EDITED
&& context.Members.Any(member =>
member.ClientID == client.ID && member.EDITED == client.EDITED && member.DELETED == client.DELETED
)
)
group contact
by new ContactDetailsViewModelPart
{
IDNumber = contact.IdNumber,
LastName = contact.LastName
}
into idNumberGroup
where idNumberGroup.Count() > 1
select idNumberGroup.Key;
return query.ToList();
Normally Any would be translated to SQL EXISTS subquery, which in turn most of the databases will treat as INNER JOIN. Unfortunatlely I don't know if Firebird does that, but it's worth trying.
Related
I want query sql where Condition And and Or in one Query in Linq. I try to coding in this below but not work. I want to query where id in CEvaUserEva or EEvaUserEva or OEvaUserEva but status must be 'success'
Plese help me.
public ActionResult Get(string id)
{
try
{
var result = (
from pre in context.PreChanges
join cus in context.PreEvaCustomers on pre.DocNumber equals cus.CDocNumber
join env in context.PreEvaEnvis on pre.DocNumber equals env.EDocNumber
join oth in context.PreEvaOthers on pre.DocNumber equals oth.ODocNumber
join sta in context.StatusDocs on pre.DocNumber equals sta.SDocNumber
select new GetAll
{
DocNumber = pre.DocNumber,
Users = pre.Users,
UserId = pre.UserId,
CDocNumber = cus.CDocNumber,
CEvaUserEva = cus.CEvaUserEva,
EDocNumber = env.EDocNumber,
EEvaUserEva = env.EEvaUserEva,
ODocNumber = cus.CDocNumber,
OEvaUserEva = oth.OEvaUserEva,
SDocNumber = sta.SDocNumber,
StatusDoc =sta.StatusDoc
})
.Where((g => g.CEvaUserEva == id || g.EEvaUserEva == id ||
g.OEvaUserEva == id && (g => g.StatusDoc== "Success"));
return Ok(result);
}
catch (Exception ex)
{
return BadRequest(ex.Message + "GetC 47");
}
}
You need parenthesis around the or block
.Where(g => (g.CEvaUserEva == id || g.EEvaUserEva == id ||
g.OEvaUserEva == id) && g.StatusDoc == "Success");
I've got this SQL statement that I'm trying to convert to linq:
SELECT i.*
FROM Issues i
WHERE IssueID IN (SELECT ChildIssueId
FROM LinkedIssues
WHERE IssueId = 28438)
OR IssueID IN (SELECT IssueId
FROM LinkedIssues
WHERE ChildIssueId = 28438)
Here's what the data in the table looks like:
So in the sql above, I get issues 19220, 28436, & 28440 back. Here's what I've tried with no luck:
var childIssues = (from i in Issues
join li in LinkedIssues
on i.IssueID equals li.IssueId
where (from li2 in LinkedIssues
where li.IssueId == 28438 || li.ChildIssueId == 28438
select li2).Contains(28438)
select new LinkedIssuesModel()
{
IssueID = li.ChildIssueId,
CustomerName = i.Room.Location.Customer.CustomerName,
LocationName = i.Room.Location.LocationName,
ReceivedDate = i.ReceivedDate,
IssueSummary = i.IssueSummary,
IssueDescription = i.IssueDescription
}).ToList();
I need to know how to convert SQL IN statements to linq. I have LinqPad but it doesn't convert it when I click the lambda button. I've also downloaded and tried Linqer but it throws an "Object not set to an instance Object" error.
Please try the following:
var childIssues = (from i in Issues
from li in LinkedIssues
where (li.IssueId == 28438 && li.ChildIssueId == i.IssueID)
|| (li.ChildIssueId == 28438 && li.IssueId == i.IssueID)
select new LinkedIssuesModel()
{
IssueID = li.ChildIssueId,
CustomerName = i.Room.Location.Customer.CustomerName,
LocationName = i.Room.Location.LocationName,
ReceivedDate = i.ReceivedDate,
IssueSummary = i.IssueSummary,
IssueDescription = i.IssueDescription
}).ToList();
EDIT: Fixed query to address li.ChildIssueId on the select.
You are not joining.
var childIssues = Issues.
Where(x => LinkedIssues.
Where(z => z.IssueId = 28438).
Select(z => z.ChildIssueId).
Contains(x.IssueID)
||
LinkedIssues.
Where(z => z.ChildIssueId = 28438).
Select(z => z.IssueId).
Contains(x.IssueID)
);
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 have a search form where the user can enter one to many parameters (Data, Status, Type, ID, Summary, Description) and leave the rest blank.
Here's my Linq to SQL code for my basic search. Is there a way to check each parameter within the Linq for zero, null or empty string?
List<RequestStatusModel> objRequestStatus = new List<RequestStatusModel>();
var query = from r in SimCareDB.Requests
where r.CustomerID == 31
select (new RequestStatusModel
{
RequestID = r.RequestID,
RequestTitle = r.RequestTitle,
DateAdded = r.DateAdded.ToString(),
DateChanged = r.DateChanged.ToString(),
RequestStatusID = r.StatusID
});
Thank you!
If it doesn't have to be in your linq statement you could just do it with classic if statements.
List<RequestStatusModel> objRequestStatus = new List<RequestStatusModel>();
var query = from r in SimCareDB.Requests
where r.CustomerID == 31
select (new RequestStatusModel
{
//...
});
if(data != null) //Replace with additional checks, if neccessary
{
query = query.where(x=> ...);
}
if(status != null)
{
query = query.where(x => ...)
}
If you want to only filter if certain criteria is passed, you should do something like this
var objRequestStatus = new List<RequestStatusModel>();
var query = from r in SimCareDB.Requests
where r.CustomerID == 31
if (String.IsNullOrEmpty(r.RequestID))
objRequestStatus = objRequestStatus.Where(x => x.RequestID == r.RequestID);
if (String.IsNullOrEmpty(r.RequestTitle))
objRequestStatus = objRequestStatus.Where(x => x.RequestTitle == r.RequestTitle);
//you other filters here
This sets up the expression to what you want based on which requests are passed
If you want to avoid all those ifs, you could do
List<RequestStatusModel> objRequestStatus = new List<RequestStatusModel>();
var query = from r in SimCareDB.Requests
where (r.CustomerID == 31) &&
(!String.IsNullOrEmpty(id) ? r.RequestID == id : true) &&
(!String.IsNullOrEmpty(status) ? r.StatusID == status : true)
/* And so on */
select (new RequestStatusModel
{
RequestID = r.RequestID,
RequestTitle = r.RequestTitle,
DateAdded = r.DateAdded.ToString(),
DateChanged = r.DateChanged.ToString(),
RequestStatusID = r.StatusID
});
I want to display the records whose accountid, id are matching and also display distinct records.
var result = from a in cxt.tblInventoryProducts
where a.aid == accID && a.id == id
select new
{
a.productType,
a.productName
};
Thanks in advance
Something like
var result = from a in cxt.tblInventoryProducts
where a.aid == accID && a.id == id
group a by new { a.productType, a.productName } into grp
select new
{
grp.Key.productType,
grp.Key.productName
};