Linq and Lambda Expression get count for group and distinct - asp.net

I've been trying to get the "Count" for my "Value" field in my query expression. In my code it suppose to create a list of checkboxes and beside the checkboxes is a count of how many items are in the list(checkbox).
Could someone show me how to get the count for the items of my field Value this is a checbox filtering system I'm making.I've just started learning linq and lambda exressions.
Code in C# ASP.NET
var dept = Page.RouteData.Values["department"];
var department = (from d in db.Departments where d.Name.Replace(" ", "-") == dept select new {d.Id, d.Name}).FirstOrDefault();
var query = (from p in db.Products
join f in db.ProductFilters on p.Id equals f.ProductId into filters
from x in filters.Where(x => x.Product.DepartmentId == department.Id)
select new { x.Id, x.Name, x.Value }).ToList();
var brand = query.Where(x => x.Name == "Brand").OrderBy(x => x.Value);
var price = query.Where(x => x.Name == "Price").OrderBy(x => x.Value);
var brandAndPrice = brand.Concat(price);
var labelBrandAndPrice = (from f in brandAndPrice select new { f.Name }).Distinct().OrderBy(x => x.Name);
//var otherFilters = query.Except(brandAndPrice);
StringBuilder sb = new StringBuilder();
sb.Append("<div class=\"Filters\">");
foreach (var label in labelBrandAndPrice)
{
sb.Append("<span>" + label.Name + "</span><br />");
sb.Append("<div class=\"ProdFilters\">");
// Below is where I wanted to do distinct expression and groupby but it didn't work
var BrandPriceCollection = brandAndPrice.Where(x => x.Name == label.Name).Distinct().ToList();
foreach (var bp in BrandPriceCollection)
{
//Here i want to write out the count for the field Value
sb.Append("<input type=\"checkbox\" id=\"" + bp.Value + "\" /><span>" + bp.Value + "(" + "Count" + ")" + "</span><br />");
}
sb.Append("</div>");
}
sb.Append("</div>");

var BrandPriceCollection = brandAndPrice.Where(x => x.Name == label.Name).Distinct().ToList();
var groupings = BrandPriceCollection.GroupBy(x => x.Value);
foreach (var g in groupings)
{
//Here i want to write out the count for the field Value
sb.Append("<input type=\"checkbox\" id=\"" + g.Key + "\" /><span>" + g.Key + "(" + g.Count() + ")" + "</span><br />");
}
GroupBy returns your data in the structure like Dictionary, with value you are grouping on in Key property and the collection of elements inside, so you can just Count() it. Note that groupings is the collection of collections now.

Related

Conversion failed when converting the varchar to data type int: SQL

I am creating a web app in asp.net mvc I have a query which looks like below
using (SqlConnection conn = new SqlConnection(_connStr))
{
conn.Open();
var p = new DynamicParameters();
p.Add("#SP_RoleId", "7,8,9", dbType: DbType.String, direction: ParameterDirection.Input);
p.Add("#SP_UserId", userId, dbType: DbType.Int32, direction: ParameterDirection.Input);
var obj = conn.Query<PendingKmsRequest>(sql: "SELECT [f].[id] AS [FileId],[fvr].[Id] AS [RequestId], [au].[Name]"
+ ", [fvr].[RequestByUserId], [fvr].[FromDate], [fvr].[ToDate],[f].[Title], [fvr].[Status], [fvr].[StatusRemarks]"
+ "FROM [dbo].[File] AS[f]"
+ "INNER JOIN [dbo].[FileViewRequest] AS [fvr] ON [f].[CurrentFileVersionId] = [fvr].[FileVersionId]"
+ "INNER JOIN [Access].[User] AS [au] ON [fvr].[RequestByUserId] = [au].[Id]"
+ "WHERE ([fvr].[Status] = 'P' OR ([fvr].[Status] = 'A' AND [fvr].[StatusByUserId] = #SP_UserId AND GETDATE() BETWEEN [fvr].[FromDate] AND [fvr].[ToDate]))"
+ "AND (SELECT 1 FROM [Access].[UserRoleMap] WHERE UserId=#SP_UserId AND RoleId IN(#SP_RoleId)) = 1", param: p, commandType: CommandType.Text);
if (obj != null && obj.Count() > 0)
return obj.ToList();
else
return new List<PendingKmsRequest>();
}
NOTE: Role id is always like (7,8,9) and it is int column in the database.
I get this conversion error on this line of code:
WHERE UserId = #SP_UserId AND RoleId IN (#SP_RoleId))
This is the error:
Conversion failed when converting the nvarchar value '7,9,10' to data type int.
How can I prevent this error?
The following line in your question code:
p.Add("#SP_RoleId", "7,8,9", dbType: DbType.String, direction: ParameterDirection.Input);
The value "7,8,9" is string and parameter type DbType.String is string as well.
But, you said this is int in your database. This is mismatch.
Further, your query:
WHERE UserId = #SP_UserId AND RoleId IN (#SP_RoleId))
The query is using IN clause.
Dapper can convert your value for IN clause if pass in an IEnumerable.
Change the line of code as below:
p.Add("#SP_RoleId", new[] {7,8,9}, dbType: DbType.Int32, direction: ParameterDirection.Input);
No need to use convert string in array or any string split() function
If you have comma saperated string then you can check it like below steps,
If you have #SP_RoleId = "7, 8, 9"
You can convert this string as below
#SP_RoleId = ",7,8,9," ( ',' + ltrim(rtrim( #SP_RoleId )) + ',' )
Now use Like to check ,UserId,
Updated code as below,
using (SqlConnection conn = new SqlConnection(_connStr))
{
conn.Open();
var p = new DynamicParameters();
p.Add("#SP_RoleId", "7,8,9", dbType: DbType.String, direction: ParameterDirection.Input);
p.Add("#SP_UserId", userId, dbType: DbType.Int32, direction: ParameterDirection.Input);
var obj = conn.Query<PendingKmsRequest>(sql: "SELECT [f].[id] AS [FileId],[fvr].[Id] AS [RequestId], [au].[Name]"
+ ", [fvr].[RequestByUserId], [fvr].[FromDate], [fvr].[ToDate],[f].[Title], [fvr].[Status], [fvr].[StatusRemarks]"
+ "FROM [dbo].[File] AS[f]"
+ "INNER JOIN [dbo].[FileViewRequest] AS [fvr] ON [f].[CurrentFileVersionId] = [fvr].[FileVersionId]"
+ "INNER JOIN [Access].[User] AS [au] ON [fvr].[RequestByUserId] = [au].[Id]"
+ "WHERE ([fvr].[Status] = 'P' OR ([fvr].[Status] = 'A' AND [fvr].[StatusByUserId] = #SP_UserId AND GETDATE() BETWEEN [fvr].[FromDate] AND [fvr].[ToDate]))"
+ "AND (SELECT 1 FROM [Access].[UserRoleMap] WHERE ',' + lTrim(rTrim(#SP_RoleId)) + ',' like '%,' + lTrim(rTrim(UserId) + ',%' " // Updated line
+ "AND RoleId IN(#SP_RoleId)) = 1", param: p, commandType: CommandType.Text);
if (obj != null && obj.Count() > 0)
return obj.ToList();
else
return new List<PendingKmsRequest>();
}

How can i Delimite and Group Json value on asp.net

I need to delimite and categorize below json value
for ex : "sub3[+]888800" sub3 is category code and 888800 is element of category.
["sub3[+]888800","sub3[+]100000","06[+]888800","06[+]100000"]
i need to result like that
sub3 -> 888800, 100000
06 - > 888800, 100000
List<string> seledItems = this.ResetSeledItems();
this.litDebug.Text = Newtonsoft.Json.JsonConvert.SerializeObject(seledItems);
var json = this.litDebug.Text;
var strs = JArray.Parse(json);
// process the delimiter
var items =
from str in strs.Select(x => (string)x)
let idx = str.IndexOf("[+]")
select new
{
tag = str.Substring(0, idx),
data = str.Substring(idx + 3)
};
// do the grouping
var grps =
from item in items
group item by item.tag into grp
select new
{
tag = grp.Key,
items = grp.Select(x => x.data)
};
foreach (var grp in grps)
{
string tag = grp.tag.ToString();
for(int i=0;i<=3 ; i++)
{
string item = grp.items.ToString();
}
}
How about the following:
// prepare the data
var json = "['sub3[+]888800','sub3[+]100000','06[+]888800','06[+]100000']";
var strs = JArray.Parse(json);
// process the delimiter
var items =
from str in strs.Select(x => (string)x)
let idx = str.IndexOf("[+]")
select new
{
tag = str.Substring(0, idx),
data = str.Substring(idx + 3)
};
// do the grouping
var grps =
from item in items
group item by item.tag into grp
select new
{
tag = grp.Key,
items = grp.Select(x => x.data)
};
// output
foreach (var grp in grps)
Console.WriteLine(grp.tag + " -> " + String.Join(", ", grp.items));
with these using clauses:
using Newtonsoft.Json.Linq;
using System;
using System.Linq;

asp:calendar binds last value to date from database

I have to bind an <asp:calendar> with data fetched from a database using a linq query.
Here is the linq code
public List<AllCalander> SearchCalender(int month, int zip, string type, int cause)
{
var xyz = (from m in DB.Calenders
where(m.DateFrom.Value.Month==month || m.Zip==zip || m.ActivityType==type || m.CauseID==cause)
group m by new { m.DateFrom } into grp
select new
{
caustitle = grp.Select(x => x.Caus.CauseTitle),
datfrm = grp.Key.DateFrom,
total = grp.Count()
})
.ToList()
.Select(m => new AllCalander
{
DateFrom =Convert.ToDateTime(m.datfrm),
CauseTitle = string.Join(",", m.caustitle),
Total = m.total
});
My aspx.cs code is here
List<AllCalander> calnder = calbll.SearchCalender(mnth,ZipString,type,causeString);
foreach (var myItem in calnder)
{
string datetime = myItem.DateFrom.ToString();
Literal myEventNameLiteral = new Literal();
myEventNameLiteral.ID = i + myItem.CauseID.ToString();
// string currentcalanderDate = e.Day.Date.Day.ToString() ;
if (string.Equals(DateTime.Parse(datetime).ToString("MMM dd yyyy"), e.Day.Date.ToString("MMM dd yyyy")))
{
string a = myItem.CauseTitle;
if (a != cause)
cause = a;
coun++;
myEventNameLiteral.Mode = LiteralMode.PassThrough;
myEventNameLiteral.Text = "<br /><span style='font-family:verdana; font-size:10px;'>" + myItem.CauseTitle + "(" + myItem.Total + ")"+ " ";
e.Cell.Controls.Add(myEventNameLiteral);
}
i++;
}
but on output it only shows the last value from database instead of showing all the data.
Can somebody please tell me what's wrong?
Thanks in advance
group m by new { m.DateFrom, m.Caus.CauseTitle } into grp

Unable to Use IsLike operator on first table in nhibernate

public IEnumerable<Mp_ProviderProfile> Find(string customerName = null
, string emailId = null, string providercode = null, string providercity = null)
{
var query = Session.QueryOver<Mp_ProviderProfile>()
.JoinQueryOver<User>(x => x.AccountInfo);
if (!string.IsNullOrEmpty(customerName))
query = query.And(x => x.UserName.IsLike("%" + customerName + "%"));
if (!string.IsNullOrEmpty(emailId))
query = query.And(x => x.EmailId.IsLike("%" + emailId + "%"));
return query.List();
}
if (!string.IsNullOrEmpty(ProviderCode))
MpProviderProfiles = MpProviderProfiles
.Where(x => x.ProviderCode.IsLike("%" + ProviderCode + "%"));
Unable to get property of Mp_ProviderProfile in where condition in query
First two query of method Find is working fine but I am not able to apply is IsLike operator on this query
MpProviderProfiles = MpProviderProfiles
.Where(x => x.ProviderCode.IsLike("%" + ProviderCode + "%"));
One solution would be to split QueryOver definition into 2 pieces:
var query = Session.QueryOver<Mp_ProviderProfile>();
var userQuery = query.JoinQueryOver<User>(x => x.AccountInfo);
Now, we do have access to both parts and we can query their tables like this
// Mp_ProviderProfile
query.Where(x => x.ProviderCode.IsLike("%" + ProviderCode + "%"));
// User
userQuery.And(x => x.UserName.IsLike("%" + customerName + "%"));
NOTE: the assignment query = query.And(... is not needed. These methods (Where(), And()) will add the Restriction into inner collection

How to get a variable replaced with a field name in a LINQ?

string companyName="ABC";
var query = from q in context.Company where q.CompanyName == companyName select q;
Is there any way to replace the q.CompanyName part of the query with a string variable
so that the field used for filtering be a parametric?
I tried
string str1 = "companySize";
string str2 = "q." + str1;
string companySize = "Mid";
var query = from q in context.Company where str2 == companySize select q;
Didn't work.
Been trying to let the user choose the columns for the query.
Read more about both below option at : Dynamic query with Linq
you can use one of this
Use Dynamic LINQ library
Example for the the blog below
string strWhere = string.Empty;
string strOrderBy = string.Empty;
if (!string.IsNullOrEmpty(txtAddress.Text))
strWhere = "Address.StartsWith(\"" + txtAddress.Text + "\")";
if (!string.IsNullOrEmpty(txtEmpId.Text))
{
if(!string.IsNullOrEmpty(strWhere ))
strWhere = " And ";
strWhere = "Id = " + txtEmpId.Text;
}
if (!string.IsNullOrEmpty(txtDesc.Text))
{
if (!string.IsNullOrEmpty(strWhere))
strWhere = " And ";
strWhere = "Desc.StartsWith(\"" + txtDesc.Text + "\")";
}
if (!string.IsNullOrEmpty(txtName.Text))
{
if (!string.IsNullOrEmpty(strWhere))
strWhere = " And ";
strWhere = "Name.StartsWith(\"" + txtName.Text + "\")";
}
EmployeeDataContext edb = new EmployeeDataContext();
var emp = edb.Employees.Where(strWhere);
Predicate Builder
EXample
var predicate = PredicateBuilder.True<employee>();
if(!string.IsNullOrEmpty(txtAddress.Text))
predicate = predicate.And(e1 => e1.Address.Contains(txtAddress.Text));
if (!string.IsNullOrEmpty(txtEmpId.Text))
predicate = predicate.And(e1 => e1.Id == Convert.ToInt32(txtEmpId.Text));
if (!string.IsNullOrEmpty(txtDesc.Text))
predicate = predicate.And(e1 => e1.Desc.Contains(txtDesc.Text));
if (!string.IsNullOrEmpty(txtName.Text))
predicate = predicate.And(e1 => e1.Name.Contains(txtName.Text));
EmployeeDataContext edb= new EmployeeDataContext();
var emp = edb.Employees.Where(predicate);
If you don't want to use libraries like dynamicLINQ, you can just create the Expression Tree by yourself:
string str1 = "companySize";
string str2 = "q." + str1;
string companySize = "Mid";
var param = Expression.Parameter(typeof(string));
var exp = Expression.Lambda<Func<Company, bool>>(
Expression.Equal(
Expression.Property(param, str1),
Expression.Constant(companySize)),
param);
var query = context.Company.Where(exp);
I think the best way to do this is with built in libraries (and PropertyDescriptor type).
using System.ComponentModel;
void Main()
{
Test test = new Test();
test.CompanyName = "ABC";
object z = TypeDescriptor.GetProperties(test).OfType<PropertyDescriptor>()
.Where(x => x.Name == "CompanyName").Select(x => x.GetValue(test)).FirstOrDefault();
Console.WriteLine(z.ToString());
}
public class Test
{
public string CompanyName { get; set; }
}

Resources