Linq query syntax with PredicateBuilder? - c#

Is it possible to use PredicateBuilder with LINQ query syntax? For example, building a basic search method, with many optional parameters. How can I add a where clause based on the predicate I have built?
public List<Entities.ProjectSearchResult> GetProjects(string projectName,
string projectLaunchName,
int? projectID, int? categoryID,
int? subCategoryID)
{
var predicate = PredicateBuilder.True<Entities.Project>();
if (!String.IsNullOrWhiteSpace(projectName))
predicate = predicate.And(p => p.ProjectName.Contains(projectName));
if (!String.IsNullOrWhiteSpace(projectLaunchName))
predicate = predicate.And(p => p.ProjectName.Contains(projectLaunchName));
if (projectID.HasValue)
predicate = predicate.And(p => p.ProjectId == projectID.Value);
if (categoryID.HasValue)
predicate = predicate.And(p => p.SectorCode == categoryID.Value);
if (subCategoryID.HasValue)
predicate = predicate.And(p => p.SubSectorCode == subCategoryID.Value);
using (CHIPSDbContext db = new CHIPSDbContext())
{
var query = (from p in db.Projects
join s in db.ProjectStatus on p.ProjectStatusCode equals s.ProjectStatusCode
join b in db.ProjectBrands on p.ProjectId equals b.ProjectId into brandList
from sublist in brandList.DefaultIfEmpty()
select new Entities.ProjectSearchResult
{
ProjectID = p.ProjectId,
ProjectName = p.ProjectName,
ProjectLaunchName = p.ProjectLaunchName,
Status = s.ProjectStatusDesc,
}).AsExpandable().ToList();
return query;
}
}

Build the predicate on the type you return instead, so that it's more clear from the calling method what you filter on.
var predicate = PredicateBuilder.True<Entities.ProjectSearchResult>(); // Expression with your type
if (!String.IsNullOrWhiteSpace(projectName))
predicate = predicate.And(p => p.ProjectName.Contains(projectName));
...
using (CHIPSDbContext db = new CHIPSDbContext())
{
var query = (from p in db.Projects
join s in db.ProjectStatus on p.ProjectStatusCode equals s.ProjectStatusCode
join b in db.ProjectBrands on p.ProjectId equals b.ProjectId into brandList
from sublist in brandList.DefaultIfEmpty()
select new Entities.ProjectSearchResult
{
ProjectID = p.ProjectId,
ProjectName = p.ProjectName,
ProjectLaunchName = p.ProjectLaunchName,
Status = s.ProjectStatusDesc,
})
.Where(predicate.Expand()) // Don't forget to expand predicate
.AsExpandable()
.ToList();
return query;
}

Related

How to pull one column from second table in Linq query with join

I have the following linq query that works fine, but I am wanting to pull one column (CompanyId) from context.Emps into the results along with the results from context.BillingProfiles. How would I modify the select (select prof) below to include said column?
var query = (from prof in context.BillingProfiles
join emp in context.Emps on prof.ID equals emp.ID
join grp in context.BillingGroups on prof.GroupID equals grp.GroupID
where (prof.EndDate == null) && (grp.System == "sysGrp") && (prof.ID == id)
select prof).Distinct()
.Select(x => new OpId()
{
id = x.ID,
GroupId = x.GroupID,
OpId = x.OpID,
StartDate = x.StartDate,
EndDate = x.EndDate,
AddedOn = x.AddedOn,
AddedBy = x.AddedBy,
RemovedOn = x.RemovedOn,
RemovedBy = x.RemovedBy,
Prodid = x.ProdID,
});
Thanks
Project an anonymous object containing those too:
var query = from prof in context.BillingProfiles
join emp in context.Emps on prof.ID equals emp.ID
join grp in context.BillingGroups on prof.GroupID equals grp.GroupID
where prof.EndDate == null && prof.ID == id && grp.System == "sysGrp"
select new { prof, emp.CompanyId, grp };

Entity Framework - convert LINQ method chain with SelectMany to query syntax

I'd like to ask a following question.
I'm building a query which will return some details about stored email packages.
Relationships:
Packages 1-------N Addresses 1------N OutboundPackages
I would like to convert testOK query to expression syntax, specifically the following statement:
referenceGuids = pkg.PackageAddresses.SelectMany(s=>s.AddressOutboundPackages).Select(s=>s.Reference)
Complete example:
var test = (from stamp in IssuedStamps
join pkg in Packages.Include(i=>i.PackageAddresses) on stamp.Id equals pkg.IssuedStampId
join addr in Addresses on pkg.Id equals addr.Package_Id
join outb in OutboundPackages on addr.Id equals outb.Address_Id
where stamp.PortalUserId == "f31c2582-f663-4f2e-a9f7-d41ba138f86c" && stamp.Used
//I'd like to convert the following SelectMany LINQ method chain expression to query syntax
//let referenceGuids = pkg.PackageAddresses.SelectMany(s=>s.AddressOutboundPackages).Select(s=>s.Reference)
select new
{
StampId = stamp.Id,
RecipientEmail = pkg.PackageAddresses.FirstOrDefault(x => x.AddressType == 1).EmailAddress,
SenderEmail = pkg.PackageAddresses.FirstOrDefault(x => x.AddressType == 0).EmailAddress,
DateSent = pkg.ReceivedDate,
Remarks = stamp.Description,
Ref = referenceGuids,
Subject = pkg.Subject,
IsMassMailing = pkg.ProcessingPackageId == null || pkg.ProcessingPackageId == string.Empty
}
).ToList();
var testOK = (from stamp in IssuedStamps
join pkg in Packages.Include(i=>i.PackageAddresses.Select(s=>s.AddressOutboundPackages)).Include(i=>i.PackageAddresses) on stamp.Id equals pkg.IssuedStampId
where stamp.PortalUserId == "f31c2582-f663-4f2e-a9f7-d41ba138f86c" && stamp.Used
let referenceGuids = pkg.PackageAddresses.SelectMany(s=>s.AddressOutboundPackages).Select(s=>s.Reference)
select new
{
StampId = stamp.Id,
RecipientEmail = pkg.PackageAddresses.FirstOrDefault(x => x.AddressType == 1).EmailAddress,
SenderEmail = pkg.PackageAddresses.FirstOrDefault(x => x.AddressType == 0).EmailAddress,
DateSent = pkg.ReceivedDate,
Remarks = stamp.Description,
Ref = pkg.PackageAddresses.SelectMany(s => s.AddressOutboundPackages).Select(s => s.Reference),
Subject = pkg.Subject,
IsMassMailing = pkg.ProcessingPackageId == null || pkg.ProcessingPackageId == string.Empty
}
).ToList();
That's easy.
referenceGuids = pkg.PackageAddresses
.SelectMany(s => s.AddressOutboundPackages)
.Select(s => s.Reference)
goes to
referenceGuids = (from pa in pkg.PackageAddresses
from aop in pa.AddressOutboundPackages
select aop.Reference)

NHibernate - Inner Join between different sessions (different connections)

two different projects I want INNER JOIN statement to write out.
Include the second session of the results, but I can not get
using (ISession session = Con1.OpenSessiongeneral())
{
using (ISession session1 = Con2.OpenSessionsystem())
{
result = (from s in session.Query<AU_SalesTarget>()
join t in session.Query<AU_Terms>() on s.termId equals t.termId
join b in session1.Query<Branchs>() on s.branchId equals b.branchId
select new SalesTarget_Derogate
{
salesTargetId = s.salesTargetId,
mounth = t.month,
year = t.year,
calculateMethod = s.calculateMethod,
branchName = b.branchName
}).Skip(0).Take(50).ToList<SalesTarget_Derogate>();
}
}
list returns null
Im not sure why you get a null list, but you should use a store procedure if your SQL Server instance, support the join between different instances.
If is not supported, the solution is not elegant, you can try to get the data first, then use linq to join them like this:
using (ISession session = Con1.OpenSessiongeneral())
{
result = (from s in session.Query<AU_SalesTarget>()
join t in session.Query<AU_Terms>() on s.termId equals t.termId
select new
{
salesTargetId = s.salesTargetId,
mounth = t.month,
year = t.year,
calculateMethod = s.calculateMethod,
branchId = s.branchId
})
.Skip(0)
.Take(50)
.ToList();
}
var branchIds = result.Select(x => x.branchId)
.List();
Branchs bAlias = null;
IList<Branchs> branches = null;
using (ISession session1 = Con2.OpenSessionsystem())
{
branches = session1.QueryOver<Branchs>
.WhereRestrictionOn(x => x.branchId).IsIn(branchIds)
.Select(list => list
.Select(x => x.branchId).WithAlias(() => bAlias.branchId)
.Select(x => x.branchName).WithAlias(() => bAlias.branchName)
)
.TransformUsing(Transformers.AliasToBean<Branchs>())
.List<Branchs>();
}
result = result.Join(branches,
x => x.branchId,
x => x.branchId,
(x, y) => new SalesTarget_Derogate
{
salesTargetId = x.salesTargetId,
mounth = x.month,
year = x.year,
calculateMethod = x.calculateMethod,
branchName = y.branchName
}).ToList();

LINQ to Entities does not recognize the method 'System.Data.Entity.DbSet`1

var query = from cl in
(
from cl in _dataContext.Set<CLIENT>()
from cr in
_dataContext.Set<CLIENT_REL>()
.Where(m => m.CLIENT_CHILD_ID == cl.CLIENT_ID)
.DefaultIfEmpty()
.AsEnumerable()
select new {cl.CLIENT_ID, cl.CLIENT_NAME, cr.CLIENT_PARENT_ID, cl.CLIENT_CODE, cl.CLIENT_DESCR}
)
from pcl in
_dataContext.Set<CLIENT>().Where(p => p.CLIENT_ID == cl.CLIENT_PARENT_ID).DefaultIfEmpty()
select new ClientDetail
{
ClientId = cl.CLIENT_ID,
ClientName = cl.CLIENT_NAME,
ClientCode = cl.CLIENT_CODE,
ClientDescription = cl.CLIENT_DESCR,
ParentName = pcl.CLIENT_NAME
};
is throwing the following System.NotSupportedException
LINQ to Entities does not recognize the method 'System.Data.Entity.DbSet`1[Ika.Security.Data.Model.CLIENT_REL] SetCLIENT_REL' method, and this method cannot be translated into a store expression.
What am I doing wrong ?

Linq query with a Conditional WHERE Clause

I am new to LINQ so apologises upfront
I have the following Linq query :-
var OrdersByBranches =
from a in AllOrders
join b in AllBranchKeys
on a.BranchKey equals b.BranchKey
orderby a.Date
group a by new { a.Date, a.paymentMethod } into BranchOrderGrouped
select new
{
BranchOrderGrouped.Key.Date,
CurrencyAmount = BranchOrderGrouped.Sum(a =>
a.CurrencyAmount),
BranchOrderGrouped.Key.paymentMethod
};
I need to include a where clause in the above query ... only if a variable called
BranchKeySelected is ""
I have tried using an If Else statement and have the same above query duplicated with
one containing a where clause and one NOT. ...But When I do this .. then OrdersByBranches
is NOT available outside of the IF Statement
Would be grateful for any help
Regards
Ghost
var OrdersByBranches =
from a in AllOrders
join b in AllBranchKeys on a.BranchKey equals b.BranchKey
orderby a.Date
group a by new { a.Date, a.paymentMethod } into BranchOrderGrouped
select new {
BranchOrderGrouped.Key.Date,
CurrencyAmount = BranchOrderGrouped.Sum(a => a.CurrencyAmount),
BranchOrderGrouped.Key.paymentMethod
};
if(string.IsNullOrEmpty(BranchKeySelected ))
{
OrdersByBranches = OrdersByBranches.Where(/*blbabla*/);
}
return OrdersByBranches;
Try (and my linq is not polished)
var OrdersByBranches = from a in AllOrders
join b in AllBranchKeys on a.BranchKey equals b.BranchKey
where b.BranchKeySelected.Contains("")
orderby a.Date group a by new
{
a.Date,
a.paymentMethod
}
into BranchOrderGrouped
select new
{
BranchOrderGrouped.Key.Date,
CurrencyAmount = BranchOrderGrouped.Sum(a => a.CurrencyAmount),
BranchOrderGrouped.Key.paymentMethod
};

Categories

Resources