I have following code,
public List<MemberDto> GetMembers(out int rowCount,int pageIndex,int pageSize, string seachBy = "", string searchTerm = "", string sortBy = "", string sortDiection = "")
{
var members = (from m in context.Members
where (string.IsNullOrEmpty(searchTerm) || m.MemberNumber.Equals(searchTerm))
|| (string.IsNullOrEmpty(searchTerm) || m.LastName.Equals(searchTerm))
select m).AsEnumerable();
if (!string.IsNullOrEmpty(sortBy))
{
PropertyDescriptor prop = TypeDescriptor.GetProperties(typeof(EFModel.ClientData.Member)).Find(sortBy, true);
members = (sortDiection.ToLower() == "descnding") ? members.OrderByDescending(x => prop.GetValue(x)).ToList() : members.OrderBy(x => prop.GetValue(x)).ToList();
}
rowCount = (!string.IsNullOrEmpty(searchTerm)) ? members.Count() : rowCount = context.Members.Count() ;
members = members.Skip(pageIndex).Take(pageSize).ToList();
List<MemberDto> memberDtos = new List<MemberDto>();
mapper.Map(members, memberDtos);
return memberDtos;
}
In the above method string seachColumn value can be memberno or lastname or sometime empty. when seachColumn value is memberno. I only need to search searchTerm value in MemberNumber column.
when seachColumn value is lastname. I only need to search searchTerm value in LastName column.
sometimes searchTerm can be empty. when it happen I need all the records without considering any search terms.
Above query is working bit. the problem is that when there is a value for searchTerm, That result is given regardless of the column. How can i do this.
public List<MemberDto> GetMembers(out int rowCount,int pageIndex,int pageSize, string seachColumn = "", string searchTerm = "", string sortBy = "", string sortDiection = "")
{
var query = context.Members;
if(string.IsNullOrWhitespace(searchTerm)
{
return query.ToList();
}
//if you want to check strings equality in ignore-case mode, you should change your db collation using the link below.
return query
.Where(m => m.MemberNumber.Equals(searchTerm) || m.LastName.Equals(searchTerm))
.ToList();
}
String equality check in ef using db collation
Related
I have a number of calls for the same query but with slightly different WHERE clause, does anyone know if it's possible to pass a variable as the column name as I can't seem to acheive it.
I know the below isn't correct but just to give you an idea of what i'm trying to acheive.
public EmailUserListViewModel EmailUserListData(int CaseId, string ColumnName)
{
CaseId = CaseId,
EmailUserList = (from u in efContext.PgsUsers
where ColumnName == true
orderby u.FirstName, u.LastName
select new EmailUserListModel
{
UserId = u.Id,
Name = ((u.FirstName == null) ? "" : u.FirstName)
+ ((u.LastName == null) ? "" : " " + u.LastName),
Email = u.Email,
Checked = false
}).ToList()
};
}
I suppose you could use Reflection to dynamically retrieve the value of the property
from u in efContext.PgsUsers where (typeof(PgsUser).GetProperty(ColumnName).GetValue(u) as bool) == true
or
from u in efContext.PgsUsers where (u.GetType().GetProperty(ColumnName).GetValue(u) as bool) == true
You could write such method:
public Expression<Func<T, bool>> getExpression<T>(string columnName)
{
var param = Expression.Parameter(typeof(T));
var equal = Expression.Equal(Expression.Property(param, columnName), Expression.Constant(true));
return (Expression<Func<T, bool>>)Expression.Lambda(equal, param);
}
and use it in where:
where getExpression<YourType>("ColumnName")
I have an existing method of generating a list of every operators. I would like to modify it, to only display operators who are not in a so called 'Inactive' role- this information comes from OperatorType table, column: Role
The existing code:
public static List<TPPROperatorDetails> GetOperators()
{
return DataHelper.DbTPPRTracer.TPPROperators.Select(
op => new TPPROperatorDetails{
Id = op.Id,
FullName = op.Name,
UserName = op.UserName,
Designation = op.Position,
OperatorTypes = ParseOperatorType(op.UserType),
SignatureImage = op.SignatureImage
}).ToList();
}
You can use the Where method. Something like this
public static List<TPPROperatorDetails> GetOperators()
{
return DataHelper.DbTPPRTracer.TPPROperators
.Where(op => ParseOperatorType(op.UserType) == "Inactive")
.Select(
op => new TPPROperatorDetails{
Id = op.Id,
FullName = op.Name,
UserName = op.UserName,
Designation = op.Position,
OperatorTypes = ParseOperatorType(op.UserType),
SignatureImage = op.SignatureImage
})
.ToList();
}
I have the following function that searches a database for entries where a column called "description" have the same value. Right now it just returns the first value it finds or a default value is there isn't one.
public static NewCode GetAltCode(int altCodeVer, string descrip)
{
var sql = #"select Code, Description, VersionID from Code.CodeLookup where versionid=#vers and description=#description";
return ObjectFactory.GetInstance<IDatabaseFactory>().Query<NewCode>(sql, new { vers = altCodeVer, description = descrip, }).FirstOrDefault();
}
I have this if statement to check and make sure the result isn't null, and if it is, to say that the "code isn't found"
[Authorize(parentAction: "Edit")]
public ActionResult Lookup(string Code, int? VersionId = null)
{
var Info = VisitViews.GetDescriptionByVersionId(Code, VersionId.HasValue ? VersionId.Value : 9);
var description = string.Empty;
// CHECK FOR NULL
if (Info != null)
{
description = Info.Description;
if (VersionId == 9)
{
var altInfo = VisitViews.GetAltCode(10, description);
}
if (VersionId == 10)
{
var altInfo = VisitViews.GetAltCode(9, description);
}
}
else
description = "CODE NOT FOUND";
return Json(new { Description = description });
}
My question is, instead of doing FirstOrDefault, is there a way to store the results in an array (or even to store them in a list and call ToArray on the list)? I'm trying to get all of the codes received during the sql search instead of just one so that another function I am working on can traverse the array and place the items where they need to be in a UI.
For future reference of this post, here is the answer:
Change the return type to NewCode[] and replace .FirstOrDefault() with .ToArray()
public static NewCode[] GetAltCode(int altCodeVer, string descrip)
{
var sql = #"select Code, Description, VersionID from Code.CodeLookup where versionid=#vers and description=#description";
return ObjectFactory.GetInstance<IDatabaseFactory>().Query<NewCode>(sql, new { vers = altCodeVer, description = descrip, }).ToArray();
}
The query I need to build is this:
query = query.Where(s =>
(
(s.Title.Contains(title1) && s.EpisodeTitle.Contains(episodeTitle1))
||
(s.Title.Contains(title2) && s.EpisodeTitle.Contains(episodeTitle2)))
);
The only issue is, s.Title and s.EpisodeTitle are dynamic.
Meaning that the following variables could be part of the query:
(string title1 = null,
string title2 = null,
string episodeTitle1 = null,
string episodeTitle2 = null,
string genre = null,
string directorName = null,
string releaseYear = null,
string seasonEpisode = null,
string showTypeDescription = null)
e.g.
query = query.Where(s =>
(
(s.DirectorName.Contains(directorName) && s.ShowTypeDescription.Contains(ShowTypeDescription))
||
(s.releaseYear.Contains(releaseYear) && s.genre.Contains(genre)))
);
In ANY type of combination.
How can I construct this query without having to take into account EVERY SINGLE possibility here?
If you only need AND logic you could just call .Where() repeatedly for every attribute that requires searching on.
if(title != null) query = query.Where(x=>x.Title == title);
if(genre != null) query = query.Where(x=>x.Genre == genre);
If your query is always of a certain structure and you want to ignore null search values you could do one big query but short circuit the attribute comparison with null checks.
query = query.Where(s =>
(
((title1 == null || s.Title.Contains(title1))
&& (episodeTitle1 == null || s.EpisodeTitle.Contains(episodeTitle1))
||
((title2 == null || s.Title.Contains(title2))
&& (episodeTitle2 == null || s.EpisodeTitle.Contains(episodeTitle2))))
);
However if you need full control over the query then you will need to look at using PredicateBuilder or System.Linq.Expressions to build a specific query to search on the necessary attributes. Here is a useful tutorial on Linq.Expressions - http://msdn.microsoft.com/en-us/library/vstudio/bb882637.aspx
the best solution is to use linqExtension with LINQKIT.
using (var context = new workEntities() )
{
Dictionary<string, List<string>> dictionary = new Dictionary<string, List<string>>();
dictionary["Title"] = new List<string> {
"Network Engineer",
"Security Specialist",
"=Web Developer"
};
dictionary["Salary"] = new List<string> { ">=2000" };
dictionary["VacationHours"] = new List<string> { ">21" };
dictionary["SickLeaveHours"] = new List<string> { "<5" };
dictionary["HireDate"] = new List<string> {
">=01/01/2000",
"28/02/2014"
};
dictionary["ModifiedDate"] = new List<string> { DateTime.Now.ToString() };
var data = context.Employee.CollectionToQuery(dictionary).ToList();
}
I am trying to add a product to my DB, I need to get the category ID from another table, however i am not sure how i can do this?
Basically, i have a table with all my different categories in, and i need to pass over the text from my external web service, which will then hit the DB and get the ID of the cat its meant to be in.
Below is the code i have:
using (aboDataDataContext dc = new aboDataDataContext())
{
var match = (from t in dc.tweProducts
where t.sku == productSku
select t).FirstOrDefault();
if (match == null)
{
tweProduct tprod = new tweProduct()
{
sku = p.productcode,
categoryId = Convert.ToInt32(catid),
title = p.name,
brand = p.manufacturer,
description = p.description,
twePrice = p.price,
weight = decimal.TryParse(p.size, out weight) == true ? (int?)weight : null,
size = decimal.TryParse(p.size, out weight) == true ? (int?)weight : null,
contry = p.country,
region = p.region,
vintage = int.TryParse(p.vintage, out vintage) == true ? (int?)vintage : null,
strength = p.strength,
bottler = p.bottler,
age = int.TryParse(p.age, out age) == true ? (int?)age : null,
caskType = p.casktype,
series = p.series,
flavour = p.flavour,
stock = p.freestock,
tweUpdated = false,
stockUpdated = false,
priceUpdated = false,
dataUpdated = false,
imgPublished = false,
lastUpdated = DateTime.Now,
};
}
}
SO basically the category from the web service is passing in Category_1 (for example), I need to pass this to my DB, to get the ID for Category_1 (say its 1) then insert it into my table.
You need to use FirstOrDefault(), assuming you are getting valid, not null response from your webservice.
categoryId = Convert.ToInt32((from c in dc.Categories
where c.Name == p.category
select c.Id).FirstOrDefault()),
FirstOrDefault/First/SingleOrDefault/Single accepts a predicate:
categoryId = dc.Categories.Single(c => c.Name == p.category).Id;