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
Related
I need to return list of values from stored procedure to my model. How do I do it:
[HttpGet("{id}")]
public DataSource Get(int id)
{
DataSource ds = _dbContext.DataSources.Where(d => d.Id == id)
.Include(d => d.DataSourceParams)
.ThenInclude(p => p.SelectOptions).FirstOrDefault();
foreach(DataSourceParam p in ds.DataSourceParams)
{
if(p.TypeId == 5)
{
p.SelectOptions = _dbContext.SelectOptions.FromSql("Exec " + ds.DataBaseName + ".dbo." + "procGetTop50 " + ds.Id + ", 1").ToList();
}
}
return ds;
}
First, declare your procedure with parameters:
string sql = "myProcedure #param1, #param2";
Second, create parameters
var param1 = new SqlParameter { ParameterName = "param1", Value = param1Value};
var param2 = new SqlParameter { ParameterName = "param2", Value = param2Value };
Finally, exec the code:
info = this.DbContext.Database.SqlQuery<MyModel>(sql, param1, param2).FirstOrDefault();
This is it!
Just remember your model must match with the procedure columns. With means, if your procedure returns a column named 'MyProp' your model 'MyModel' must have a 'MyProp' property.
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; }
}
The code is working and returning a good list with (6) items.
However, we are seeing duplicates productSKU. We want to do a
DISTINCt productSKU.
pM = (from oo in ctx.option1
where mArray.Contains(oo.option1Code)
select oo)
.Select(o => new ProductMatch
{
productSKU = o.option1Code,
productPrice = o.price,
option1Desc = o.option1Desc
}).ToList();
I have tried to add Distinct() after the Lambda but I still get (6) items.
I am also getting error when I add GroupBy(...) "Cannot convert lambda expression to type 'string' because it is not a delegate type"
Try this syntax:
pM = (from o in ctx.option1
where mArray.Contains(o.option1Code)
let t = new
{
productSKU = o.option1Code,
productPrice = o.price,
option1Desc = o.option1Desc
}
group o by t into grp
select new ProductMatch
{
productSKU = grp.Key.option1Code,
productPrice = grp.Key.price,
option1Desc = grp.Key.option1Desc
}).ToList();
When you use a Distinct on a lamba expression, the Distinct only looks at the EntityKey for the distinct comparision. You will need to implement your own IEqualityComparer for your select.
internal class UniqueProductComparer : IEqualityComparer<ProductMatch>
{
public bool Equals(ProductMatch x, ProductMatch y)
{
if(Object.ReferenceEquals(x,y)) return true;
if(Object.ReferenceEquals(x, null) || Object.ReferenceEquals(y,null))
return false;
return x.productSKU == y.ProductSKU && x.productPrice == y.productPrice && x.option1Desc == y.option1Desc;
}
public int GetHashCode(ProductMatch match)
{
if (Object.ReferenceEquals(match,null)) return 0;
return match.productSKU.GetHashChode() + match.productPrice.GetHashCode() + match.option1Desc.GetHashCode();
}
}
Then in your lamba, change it to this:
pM = (from oo in ctx.option1
where mArray.Contains(oo.option1Code)
select oo)
.Select(o => new ProductMatch
{
productSKU = o.option1Code,
productPrice = o.price,
option1Desc = o.option1Desc
}).Distinct(new UniqueProductComparer()).ToList();
A slight variation of IAbstractDownvoteFactor's answer
pM = (from oo in ctx.option1
where mArray.Contains(oo.option1Code)
select oo)
.GroupBy(o => o.option1Code)
.Select(g => g.First())
.Select(o => new ProductMatch
{
productSKU = o.option1Code,
productPrice = o.price,
option1Desc = o.option1Desc
}).ToList();
Alternatively, if you use linq heavily and are open to using libraries, there is morelinq that gives you DistinctBy() extension and several other useful extensions.
I having a trouble with a query
I need to take out the SHIPMENT from GetAllOrderData - the same place where you can find POD_DATE and RECEIVE_NAME...but I get an error
Error 1 The name 'x' does not exist in the current context
My code is:
public IEnumerable<ReportItemDTO> GetTaskProgress(DateTime targetDate)
{
try
{
var startDate = targetDate.Date;
var endDate = startDate.AddDays(1);
OrderDataRepository rep = new OrderDataRepository();
var query = rep.GetAllOrderData()
.Where(x => x.POD_DATE >= startDate && x.POD_DATE <= endDate)
.GroupBy(o => o.User)
.Select(g => new ReportItemDTO
{
DriverId = g.Key.Id,
PdriverName = g.Key.Name,
OrderCount = g.Count(),
ReportedOrdersCount = g.Count(o => o.RECEIVE_NAME != null),
SHIPMENT = (x.SHIPMENT)
} );
return query;
SHIPMENT = (x.SHIPMENT)
Well you are within a grouping when you try to make that assignment - there are many shipments in each grouping not just one - in fact all shipments for that particular user. Assuming you want a collection of them you could do:
Shipments = g.Select( x=> x.SHIPMENT)
Edit:
If you just want the first shipment for each user (somewhat illogical but fits your data model):
SHIPMENT = g.Select( x=> x.SHIPMENT).First()
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.