Convert Linq Query Expression to Method Syntax equivalent - linq

I use LINQ, C#, EF4.
I have this query expression in Linq. I need to convert in a equivalent in Method Syntax but I have some doubt on the struction. Could you provide me a good example. Thanks for your help.
var myContentsForAuthor = from c in context.CmsContents
join a in context.CmsAuthors on c.AuthorId equals a.AuthorId
join u in context.aspnet_Users on a.UserId equals u.UserId
orderby c.Title ascending
where u.UserId == myUserGuid && c.IsDeleted == false && c.Title.Contains(nameSearchString)
select c;

Well, this gets complicated because of the transparent identifiers, but something like:
var myContentsForAuthor = context.CmsContents
.Join(context.CmsAuthors,
c => c.AuthorId
a => a.AuthorId,
(c, a) => new { c, a })
.Join(context.aspnet_Users,
z => z.a.UserId,
u => u.UserId,
(z, u) => new { z, u })
.OrderBy(zz => zz.z.c.Title)
.Where(zz => zz.u.UserId == myUserGuid &&
zz.z.c.IsDeleted == false &&
zz.z.c.Title.Contains(nameSearch))
.Select(zz => zz.z.c);

Related

Convert linq query to lambda expression

I am having trouble converting this linq query to a lambda expression, I tried to solve it using include but not successful, please help
(from PS in _dbNavigation.Table1
join CP in _dbNavigation.Table2 on PS.PropName equals CP.PropName
where PS.IsDeleted == false && PS.UserName.Equals("REX")
select CP).ToList();
_dbNavigation.Table1
.Join(_dbNavigation.Table2, t1 => t1.PropName, t2 => t2.PropName, (t1, t2) => new { t1, t2 })
.Where(x => x.t1.IsDeleted == false && x.t2.UserName == "REX")
.Select(x => x.t2);

linq groupjoin using lambda with a where clause

I need to add a join using Lambda if I have a further parameter available that will also be used in a where clause.
My problem is I'm not sure of the exact format for adding a new object MemberTagLysts and then how the where clause should be created.
var tagList = from t in dc.Tags
join b in dc.Businesses on t.BusinessId equals b.BusinessId
where t.IsActive == true
where b.IsActive == true
orderby t.AdImage descending
select new TagItem
{
tagName = t.Name.Replace("\"", ""),
tagImage = tagImagePath + t.AdImage.Replace("\"", ""),
tagDescription = t.Description.Replace("\"", "")
};
if (!string.IsNullOrEmpty(lystId))
{
tagList = (IQueryable<TagItem>)tagList.GroupJoin(dc.MemberTagLysts, a => a.tagId, b => b.TagId, (a, b) => new { a, b });
}
I think you want to do something like this:
var tagList = from t in dc.Tags
join b in dc.Businesses on t.BusinessId equals b.BusinessId
where t.IsActive
where b.IsActive
orderby t.AdImage descending
select new TagItem
{
tagName = t.Name.Replace("\"", ""),
tagImage = tagImagePath + t.AdImage.Replace("\"", ""),
tagDescription = t.Description.Replace("\"", "")
};
if (!string.IsNullOrEmpty(lystId))
{
tagList = tagList
.GroupJoin(dc.MemberTagLysts.Where(l => l.lystId == lystId),
a => a.tagId,
b => b.TagId,
(a, b) => new { a, b }));
}
Conditionally expanding the query is good practice. Note that conditions like where t.IsActive == true are redundant, where t.IsActive is enough and arguable better readable with well-chosen property names (as you have).

What is the lambda equivalent of this Linq query?

What is the equivalent lambda syntax to this linq query?
Dim query = From t In _rdsqlconn.Tags Where t.TagWord = tag
Join p In _rdsqlconn.Posts On t.PostId Equals p.PostId Order By p.PostDatePublished
Descending Select p Where p.PostIsPublished = True
You can do this with a join, like so:
_rdsqlconn.Tags
.Where(t => t.TagWord == tag)
.Join(_rdsqlconn.Posts, t => t.PostId, p => p.PostId, (t, p) => p)
.Where(p => p.PostIsPublished == true)
.OrderByDescending(p => p.PostDatePublished)
but what you want to do is properly map your tables and relationships in the LINQ-to-SQL designer, and then you can use
_rdsqlconn.Posts.Where(p => p.PostIsPublished && p.Tags.Any(t => t.TagWord == tag))
.OrderByDescending(p => p.PostDatePublished)
If you have a foreign key between Posts and Tags in your database then you will be able to do this. It's much cleaner code, and removes the unnecessarily Join operator.

Linq strangeness

I was receiving repeating rows from this linq query:
public static Func<DataContext, string, IQueryable<Building>>
GearFilteredBuildings =
CompiledQuery.Compile((DataContext db, string filter) =>
from b in db.Building
join r in db.Router on b equals r.Building
orderby !b.Active
where filter.Length == 5 && r.Name.Substring(1, 5).ToLower() == filter
|| filter.Substring(0, 3) == r.Name.Substring(3, 3).ToLower()
select b);
After some fiddling, I got the distinct Buildings with this:
public static Func<DataContext, string, IQueryable<Building>>
GearFilteredBuildings =
CompiledQuery.Compile((DataContext db, string filter) =>
(from b in db.Building
join r in db.Router on b equals r.Building
orderby !b.Active
where filter.Length == 5 && r.Name.Substring(1, 5).ToLower() == filter
|| filter.Substring(0, 3) == r.Name.Substring(3, 3).ToLower()
group b by b.Id into g
select g) as IQueryable<Building>);
Is this an acceptable solution? How else might this be done?
Not sure (couldn't test it IDE) but select...join...lalala can replaced with Linq-Chain syntax:
db.Routers
.Where(r => filter.Length == 5 && r.Name.Substring(1, 5).ToLower() == filter || filter.Substring(0, 3) == r.Name.Substring(3, 3).ToLower())
.GroupBy(r => r.Building)
.Select(g => g.Key)
.OrderBy(b => !b.Active)
Also: as I can see no joins are really requred in your query, as you have navigation properties (r.Building)in your model.
Or another approach could be used, select all needed buildings, and use .Distinct() afterwards:
db.Routers
.Where (r => filter.Length == 5 && r.Name.Substring(1, 5).ToLower() == filter || filter.Substring(0, 3) == r.Name.Substring(3, 3).ToLower())
.Select(r => r.Building)
.Distinct()
.OrderBy(b => !b.Active)

Linq include with where clause

Hey so I've got the situation where I'm pulling a client back from the database and including all the case studies with it by way of an include
return (from c in db.Clients.Include("CaseStudies")
where c.Id == clientId
select c).First();
but what I want to do now is and a where clause on the included casestudies so that it only returns the case studies where deleted = false
sort of like this
return (from c in db.Clients.Include("CaseStudies")
where c.Id == clientId
&& c.CaseStudy.Deleted == false
select c).First();
But this doesn't work :( any ideas
Conditional includes are not supported out-of-the-box in EF v1.0. But Alex James has a bit hacky workaround for that explained well here: http://blogs.msdn.com/alexj/archive/2009/10/13/tip-37-how-to-do-a-conditional-include.aspx
var dbquery =
from c in db.Clients
where c.Id == clientID
select new {
client = c,
caseStudies = from cs in c.CaseStudy
where cs.Deleted==false
select cs
};
return dbquery
.AsEnumerable()
.Select(c => c.client);
Also, I haven't succeeded to make this workaround work with many-to-many relationships.
You can return a similar group of records this way, the GroupBy is going to make the enumeration different, but its not difficult.
CaseStudies.Include("Client")
.Where(c => !c.Deleted && c.Client.ID == ClientID)
.GroupBy(c => c.Client.ID);
One option is to perform a query on your results, like this:
var results = (from c in db.Clients.Include("CaseStudies")
where c.Id == clientId
select c).First();
results.CaseStudies = (from c in results.CaseStudies
where c.Deleted == false
select c).ToList();
Or of course you can use a lambda expression:
var results = db.Clients
.Include(c => c.CaseStudies)
.Where(c => c.ID == clientId).First();
results.CaseStudies = results.CaseStudies.Where(c => !c.Deleted).ToList();

Resources