How to write if condition inside where clause in linq - asp.net-mvc

I want to write if condition inside where clause. because if first name or last name is null I don't wani to add it in where clause . other wise I want to add it.
so I write
var query1 = from opv in _opvRepository.Table
join o in _orderRepository.Table on opv.OrderId equals o.Id
join gr in _graduandRepository.Table on opv.graduand_id equals gr.graduand_id
join pv in _productVariantRepository.Table on opv.ProductVariantId equals pv.Id
join p in _productRepository.Table on pv.ProductId equals p.Id
where (opv.ceremony_id == ceremony_id) &&
(!o.Deleted) && (opv.IsHireItem == true) &&
(!p.Deleted) &&
(!pv.Deleted) && (opv.ceremony_id == ceremony_id)
// group opv by opv.OrderId into g
select new
{
opvTable = opv,
grTable = gr,
};
// This is not working. I have problem in here. How to add this??
if (!String.IsNullOrEmpty(Fname))
query1 = query1.Where(grTable = > grTable.first_name == Fname);
var result = query1.ToList().Select(x =>
{
return new HireItemReportLine()
{
OrderId = x.opvTable.OrderId,
OrderDate=x.opvTable.Order.CreatedOnUtc,
Amount= x.opvTable.Order.OrderSubtotalExclTax,
PaymentMethod = x.opvTable.Order.PaymentMethodSystemName,
paidDate = x.opvTable.Order.CreatedOnUtc,
Fname = x.grTable.first_name,
MName = x.grTable.middle_name,
LName = x.grTable.last_name,
};
}).ToList();
What is the wrong with my cording??

Note that your original query selects an anonymous type with two properties: opvTable and grTable. So, you need to use one of those properties in the subsequent Where clause, like this:
query1 = query1.Where(item => item.grTable.first_name == Fname);

Related

Linq Query to fetch data using non entity object

I'm trying to fetch the record from 3 tables by comparing the user Logged in name
Here is my code:
public ActionResult MeritList() //departmental merit listed students details with status 1
{
var username= HttpContext.Session["UserName"];
List<StdListModel> model = new List<StdListModel>();
var query = (from s in Context.tblStdDetails
join e in Context.tblStdEnrollments on s.ID equals e.StdReg_ref_id
//join d in Context.tblDepartments on e.Depart_ref_id equals d.ID
where s.Status == '1' && e.tblDepartment.DepartName == username
select new StdListModel
{
ID = s.ID,
Name = s.Name,
FatherName = s.FatherName,
CNIC = s.CNIC,
FormNo = s.FormNo,
DiaryNo = s.DiaryNo,
Status = s.Status
}).ToList();
foreach(var item in query)
{
model.Add(new StdListModel()
{
ID=item.ID,
Name=item.Name,
FatherName=item.FatherName,
CNIC=item.CNIC,
FormNo=item.FormNo,
DiaryNo=item.DiaryNo
});
}
return View(model);
}
Also Tried this Query
var query = (from s in Context.tblStdDetails
join e in Context.tblStdEnrollments on s.ID equals e.StdReg_ref_id
join d in Context.tblDepartments on e.Depart_ref_id equals d.ID
where s.Status == '1' && d.DepartName.Equals(username)
select new StdListModel
{
ID = s.ID,
Name = s.Name,
FatherName = s.FatherName,
CNIC = s.CNIC,
FormNo = s.FormNo,
DiaryNo = s.DiaryNo,
Status = s.Status
}).ToList();
But it does not return anything model=0, query =0, the database has right values and I don't get any error either.
please check username with tolower() and trim function.
e.tblDepartment.DepartName.ToLower().Trim() == username.ToLower().Trim()
or
e.tblDepartment.DepartName.ToLower().Trim().equals(username.ToLower().Trim())
I got the problem. It is in
s.Status == '1'
I just changed it into
s.Status == 1
and it works fetch the data from the database.

A query body must end with a select clause or a group clause in LINQ Query

model.ListManagerReviewerMapping = (from a in wallet.OM_Employee
join m in wallet.APPR_ManagerMapping
on a.AssociateId equals m.AssociateId
where m.ManagerId==Context.UserId.Value **into** MM
from leftjoinresult in M.DefaultIfEmpty()
where a.CompanyId == Context.CompanyId && (a.TermStatus == "L" || a.SeparationDate > DateTime.Today)
select new ManagerAndReviewerMappingModel.ManagerAndReviewerMapping()
{
Photo = (photoUrl + "?AssociateCode=" + a.AssociateCode),
AssociateId = a.AssociateId,
AssociateCode = a.AssociateCode,
AssociateName = a.AssociateName
}).ToList();
You need to use Where extension method for first query, as the query uses left join with DefaultIfEmpty (note that you can't use into after where clause since where must be followed with select to finish the query):
model.ListManagerReviewerMapping = (from a in wallet.OM_Employee
join m in wallet.APPR_ManagerMapping.Where(x => x.ManagerId == Context.UserId.Value)
on a.AssociateId equals m.AssociateId into MM
from leftjoinresult in MM.DefaultIfEmpty()
where a.CompanyId == Context.CompanyId && (a.TermStatus == "L" || a.SeparationDate > DateTime.Today)
select new ManagerAndReviewerMappingModel.ManagerAndReviewerMapping()
{
Photo = (photoUrl + "?AssociateCode=" + a.AssociateCode),
AssociateId = a.AssociateId,
AssociateCode = a.AssociateCode,
AssociateName = a.AssociateName
}).ToList();
Similar issues:
LINQ LEFT JOIN where clause not working
LINQ Left Join And Right Join
//Remove brackets and .ToList();
model.ListManagerReviewerMapping = from a in wallet.OM_Employee
join m in wallet.APPR_ManagerMapping
on a.AssociateId equals m.AssociateId
where m.ManagerId==Context.UserId.Value **into** MM
from leftjoinresult in M.DefaultIfEmpty()
where a.CompanyId == Context.CompanyId && (a.TermStatus == "L" || a.SeparationDate > DateTime.Today)
select new ManagerAndReviewerMappingModel.ManagerAndReviewerMapping()
{
Photo = (photoUrl + "?AssociateCode=" + a.AssociateCode),
AssociateId = a.AssociateId,
AssociateCode = a.AssociateCode,
AssociateName = a.AssociateName
};

LINQ to Entities does not recognize the method,and this method cannot be translated into a store expression

i have an action as :
var viewModel = (from o in db.Sepet
join q2 in db.Urunler on o.urun_id equals q2.urun_id
join m in db.Markalar on q2.marka_id equals m.marka_id
where (o.sepet_id == bskt_id && o.statu == 0)
select new SepetView
{
urun_id = q2.urun_id,
urun_resmi = q2.resimlink,
urun_link = q2.urun_link,
urun_adi = q2.urun_adi,
urun_fiyat = FiyatGetir(q2.gununfirsati,q2.urun_fiyat,q2.kampanyafiyati),
adet = o.adet,
sepettutari = (o.adet * FiyatGetir(q2.gununfirsati, q2.urun_fiyat, q2.kampanyafiyati)),
marka_adi = m.marka_adi,
}).ToList();
and have a method (FiyatGetir) as :
public static decimal FiyatGetir(DateTime tarih,decimal urunfiyat,decimal kampanyalifiyat)
{
decimal fiyat;
if (tarih == DateTime.Now)
fiyat = kampanyalifiyat;
else
fiyat = urunfiyat;
return fiyat;
}
it gives an error : LINQ to Entities does not recognize the method,.....and this method cannot be translated into a store expression.
How can i resolve that?
Everything between the parentheses is an expression. Entity Framework will try to translate this whole expression into SQL, which means that every part (token) of the expression must have an explicit mapping to a SQL equivalent. Of course, for FiyatGetir there isn't such a mapping because it's an unknown method (to EF).
As said in a comment, it's not hard to move the logic into the LINQ query itself, but you need it twice, so it's better to use the let keyword:
var viewModel = (from o in db.Sepet
join q2 in db.Urunler on o.urun_id equals q2.urun_id
join m in db.Markalar on q2.marka_id equals m.marka_id
where (o.sepet_id == bskt_id && o.statu == 0)
let fiyat = q2.gununfirsati == DateTime.Today
? q2.kampanyafiyati
: q2.urun_fiyat
select new SepetView
{
urun_id = q2.urun_id,
urun_resmi = q2.resimlink,
urun_link = q2.urun_link,
urun_adi = q2.urun_adi,
urun_fiyat = fiyat,
adet = o.adet,
sepettutari = (o.adet * fiyat),
marka_adi = m.marka_adi,
}).ToList();
Note that I changed the reference date/time to DateTime.Today. The chance that q2.gununfirsati exactly equals DateTime.Now is vitually zero, so I assume that's not correct. Maybe you should truncate q2.gununfirsati before the comparison (DbFunctions.TruncateTime).

LINQ multiple where statement mvc

This code works only if I complete the 3 fields:
website, author, and content.
I want to complete 1 field, 2 fields or 3 fields (non completed fields are null) and search according to that
var posts = from p in db.Posts
where ((p.PostDate >= fd && p.PostDate <= td)
&& p.WebSite.Equals(WebSite)
&& p.PostAuthor.Contains(Author)
&& p.PostText.Contains(Content)
|| WebSite == null || Author == null || Content == null)
select p;
I tried this code but don't working too:
var posts = from p in db.Posts
select p;
if (WebSite != null)
{
posts = from p in db.Posts
where p.WebSite.Equals(WebSite)
select p;
}
if (Author != null)
{
posts = from p in db.Posts
where p.PostAuthor.Contains(Author)
select p;
}
if (Content != null)
{
posts = from p in db.Posts
where p.PostText.Contains(Content)
//Count and date is missing
select p;
}
return View("Index", posts);
I need like this for 1 parameter but for 3:
var posts = from p in db.Posts
where p.PostTitle.Contains(searchTerm) || searchTerm==null
select p;
return View(posts);
First you need to prepare non filtered IQueryable object without selecting the output:
IQueryable<Post> query = from p in posts;
Then apply filter according to your filter conditions
if (webSite != null)
{
posts = posts.Where(p => p.WebSite.Contains(webSite));
}
if (author != null)
{
posts = posts.Where(p => p.PostAuthor.Contains(author));
}
Finnaly run query
var result = posts.ToArray();
Another approach is to create fulltext index on the table and search by fulltext in indexed columns. It has better results then searching in the three fields separately.
Change your code to this:
var posts = from p in db.Posts
select p;
if (!string.IsNullOrEmpty(WebSite))
{
posts = from p in posts
where p.WebSite.Equals(WebSite)
select p;
}
if (!string.IsNullOrEmpty(Author))
{
posts = from p in posts
where p.PostAuthor.Contains(Author)
select p;
}
if (!string.IsNullOrEmpty(Content))
{
posts = from p in posts
where p.PostText.Contains(Content)
//Count and date is missing
select p;
}
return View("Index", posts.ToList());
An empty string is not the same as a null string.
Edit: you should probably execute the query before sending it to the view.
Using LINQ to Entities:
var posts = db.Posts.AsQueryable();
if (!string.IsNullOrEmpty(WebSite))
posts = posts.Where(p => p.WebSite.Equals(WebSite));
if (!string.IsNullOrEmpty(Author))
posts = posts.Where(p => p.PostAuthor.Contains(Author));
if (!string.IsNullOrEmpty(Content))
posts = posts.Where(p => p.PostText.Contains(Content));
return View("Index", posts.ToList());
Solution:
var posts = from p in db.Posts
where ((string.IsNullOrEmpty(WebSite) || p.WebSite.Equals(WebSite))
&& (string.IsNullOrEmpty(Author) || p.PostAuthor.Contains(Author))
&& (string.IsNullOrEmpty(Content) || p.PostText.Contains(Content))
)
select p;
Try the following:
var posts = from p in db.Posts
where ((p.PostDate >= fd && p.PostDate <= td)
&& ((string.IsNullOrEmpty(WebSite) || p.WebSite.Equals(WebSite))
|| (string.IsNullOrEmpty(Author) || p.PostAuthor.Contains(Author))
|| (string.IsNullOrEmpty(Content) || p.PostText.Contains(Content)))
)
select p;
Just replace db.Posts with posts in the three conditional searches, so for the first one:
if (WebSite != null)
{
posts = from p in posts
where p.WebSite.Equals(WebSite)
select p;
}

LINQ convert DateTime to string

List<Post> list =
(
from c in db.TitleComments
join t in db.Titles on c.TitleId equals t.Id
join u in db.Users on c.UserId equals u.Id
where t.Id == _titleId && c.Date > time
orderby c.Date descending
select new Post { Username = u.Username, PostingDate = c.Date.ToString(), Data = c.Comment }
).ToList();
The code above causes exception on the convertion of date to string, PostingDate = c.Date.ToString(). Any ideas how to get around this?
Exception error:
{"LINQ to Entities does not recognize the method 'System.String ToString()' method, and this method cannot be translated into a store expression."}
linq is trying to convert date to string using sql but since there is no ToString() method in sql it can't convert it, this behavior is by design - Joakim
In other words, return the date itself and convert it to a string after it executes on SQL side:
(
select new { Username = u.Username,
PostingDate = c.Date
[...]
})
.ToList() // runs on SQL and returns to the application
.Select(o => // is not generating a SQL, it is running on the app
new Post { Username = o.Username,
PostingDate = o.PostingDate.ToString(),
[...]
})
You can remedy your problem by projecting into an anonymous type, and then at a later step project into Post after the data has already been returned from the DB.
(from ....
select new { /* stuff */, Date = c.Date })
.AsEnumerable()
.Select(p => new Post { /* stuff */, PostingDate = p.Date.ToString() })
.ToList();
However, given that you have a property called PostingDate, the original source being a date, I would recommend your revise your object to actually keep the value as a DateTime instead of a string.
I dont think this can be done in a direct way.
var list =
select new Post { Username = u.Username, PostingDate = SqlFunctions.StringConvert(c.Date), Data = c.Comment }
from
(from c in db.TitleComments
join t in db.Titles on c.TitleId equals t.Id
join u in db.Users on c.UserId equals u.Id
where t.Id == _titleId && c.Date > time
orderby c.Date descending).AsEnumerable()
).ToList();
Also with EF4 you can try something like this:
List<Post> list =
(
from c in db.TitleComments
join t in db.Titles on c.TitleId equals t.Id
join u in db.Users on c.UserId equals u.Id
where t.Id == _titleId && c.Date > time
orderby c.Date descending
select new Post { Username = u.Username, PostingDate = SqlFunctions.DateName(c.Date), Data = c.Comment }
).ToList();

Resources