How do I get a space in my property name? - c#

I have the following query:
var query = _projectEmployeesBLL.GetAll()
.Where(x => x.EmployeeID == employee.EmployeeID
&& x.project.isActive == true
&& x.project.isDelected == false)
.Select(x => new
{
x.project.ProjectID,
ProjeAdı = x.project.Name,
});
The problem is that I make the property ProjeAdı in the Select clause. I want the property to match the sql column, Proje Adı (note the space). How can I do that?

while this might not be useful in your case, someone else looking for a way can use the 'DisplayName' attribute that can come in handy when enumerating properties as propertiesDescriptor.
I had a similar requirement.
here's how to use it-
[DisplayName("Father Name")]
public string FatherName{get;set;}
then access it using
propertyDescriptor.DisplayName
or byways shared here

aliases cant have spaces between them , just like any variable name cant have white space, they are considered as bad naming conventions, you can use _(underscore) eg. Proje_Adi

Related

C# Chaining multiple LINQ contains to search for user

I am trying to add a user to a team by searching through a list of users.
I am using linq to search through the data to find a match based on a number of fields
data = data.Where(x =>
x.Name.ToLower().Contains(filter) ||
x.Surname.ToLower().Contains(filter) ||
x.PhoneNumber.ToLower().Contains(filter) ||
x.Email.ToLower().Contains(filter) ||
x.AthleteTeams.All(x => x.Team.Name.Contains(filter)) ||
x.AthleteTeams.All(x => x.Athlete.AthleteGender.Equals(filter)) ||
x.AthleteTeams.All(x => x.Athlete.AthleteRace.Equals(filter))
);
However, the results work only with name, surname and email.
When all the fields are searched it gives back seemingly random users instead of those that meet the specified filter
I guess that you dont want to find all users which AthleteTeams have ALL the same team-name, for example. That would mean you have multiple teams with a similar name.
I guess that you actually want to find all users which AthleteTeams contain at least ONE team with matching name, for example. So use Any and also use only one query of AthleteTeams instead of three:
....
x.AthleteTeams.Any(x => x.Team.Name.Contains(filter)
|| x.Athlete.AthleteGender.Equals(filter)
|| x.Athlete.AthleteRace.Equals(filter))
However, i find this filter logic strange and error-prone. You will have a slow search performance and many false matches, because always something matches and the user doesn't know why. Better provide a search through the most common properties like the names and phone-number, don't start to search before the user enters at least 3 characters and provide a specific team-search.
However, the results work only with name, surname and email.
I think PhoneNumber should be fine too.
When all the fields are searched it gives back seemingly random users instead of those that meet the specified filter
Enumerable.All for empty collection will always be true:
Console.WriteLine(new int[]{}.All(i => false)); // prints True
Try using something like:
data = data.Where(x =>
... || (x.AthleteTeams.Any() && (
x.AthleteTeams.All(x => x.Team.Name.Contains(filter)) ||
x.AthleteTeams.All(x => x.Athlete.AthleteGender.Equals(filter)) ||
x.AthleteTeams.All(x => x.Athlete.AthleteRace.Equals(filter))))
);
Also possibly you actually need Any instead of All in the first place:
data = data.Where(x =>
...
|| x.AthleteTeams.Any(x => x.Team.Name.Contains(filter)
|| x.Athlete.AthleteGender.Equals(filter)
|| x.Athlete.AthleteRace.Equals(filter))
);

LINQ filter returned objects

I have this snippet in a WPF project, and I want to modify the returned objects to include only CardGroup items that have company_id = ?. Not sure how to do it, never done WPF before and never seen a snippet where the results are immediately returned as ojects like here?
WOuld be great if someone could just give me a heads up on the solution (which is probably pretty simple I would assume, but can't figure out where to place the limitation code).
public List<CompanyComboData> AvailableCardGroupsForCompany(int companyId)
=> _dataService.GetAll<CardGroup>().Select(x => new CompanyComboData
{
Id = x.Id,
Value = x.Name
}).ToList();
Many thanks in advance!
You can filter using "Where". For example:
_dataService.GetAll<CardGroup>().Where(c => c.company_id == ?).Select(...
EDIT to change = to ==
_dataService.GetAll<CardGroup>().Where(x=> x.company_id == myCompanyId)

Linq: Removing Group By but still get its items?

Just some details. Get Records is a variable where it contains the results of my stored procedure. Now, what I want to ask is what if I want to remove the group by function but I still want to get the key and items? Is there a way to do it?
var sortResCinema = GetRecords.Where(x => test2.branch == x.Bbranch && test.movieName == x.MovieName && x.MovieName != null)
.GroupBy(x => x.MovieName,
(key, elements) =>
new
{
Id = key,
Items = elements.ToList()
}).ToList();
There's no need for GroupBy here since you are looking for a specific movieName.
I guess you wanted something like this:
var sortResCinema = GetRecords.Where(x => test2.branch == x.Bbranch && test.movieName == x.MovieName).ToList();
You can replace the GroupBy with a Select. The Select statement can be used to alter the type of the results returned, which is what you appear to want to do. Should work with exactly the same syntax as the second parameter. So replace "GroupBy" with "Select" and remove the first argument. The key and elements properties that are being used in the GroupBy statement are internal to that function so you'd need to work out what function you want to replace these by, for instance the key might be x.MovieName.

how do I handle spaces in peoples name when I run a query

I am running the following query:
if (!string.IsNullOrWhiteSpace(accountHolderName))
{
Customer cust = _entities.Customers.FirstOrDefault(c => c.AccountId == acct.AccountId &&
c.CorporationId == token.CorporationId &&
c.Name.ToUpper().StartsWith(accountHolderName.ToUpper()));
}
The record that I'm searching for has the Name of 'MC CARTAN'.
What the customer is actually putting is 'MCCARTAN'. So, it's not getting any results.
Is there a way to query and ignore spaces in the name?
On a side note, can I ignore case also?
Thanks!
LINQ to Entities supports string.Replace() instance method, so you can try following:
c.Name.Replace(" ", "").ToUpper().StartsWith(accountHolderName.ToUpper())
You could make a routine in the database to normalize the names, for instance by removing all spaces, and a corresponding one in C#, and then compare the normalized versions.
Customer cust = _entities.Customers.FirstOrDefault(c => c.AccountId == acct.AccountId &&
c.CorporationId == token.CorporationId &&
c.Name.Normalize().StartsWith(Normalize(accountHolderName));
This link talks all about custom functions in the database.
If the cleanup that you need to do on the names is limited to simple string operations that LINQ already supports in the database, then you can do as the other answers suggest and just use those. I was trying to address the case where the string operations aren't as straightforward
Your code should already handle casing (use of ToUpper), by using the Replace function to replace a space with no space, it should take care of that as well.
if (!string.IsNullOrWhiteSpace(accountHolderName))
{
Customer cust = _entities.Customers.FirstOrDefault(c => c.AccountId == acct.AccountId &&
c.CorporationId == token.CorporationId &&
c.Name.Replace(" ","").ToUpper().StartsWith(accountHolderName.Replace(" ","").ToUpper()));
}
Try to use
accountHolderName.Replace(" ", "%").ToUpper()
If you want to ignore all the spaces, then probably you should replace them by nothing:
name = name.Replace(" ", "");
To ignore the case, then you should do like this:
name.Equals(other_name, StringComparison.InvariantCultureIgnoreCase);

Dynamic WHERE clause in LINQ

What is the best way to assemble a dynamic WHERE clause to a LINQ statement?
I have several dozen checkboxes on a form and am passing them back as: Dictionary<string, List<string>> (Dictionary<fieldName,List<values>>) to my LINQ query.
public IOrderedQueryable<ProductDetail> GetProductList(string productGroupName, string productTypeName, Dictionary<string,List<string>> filterDictionary)
{
var q = from c in db.ProductDetail
where c.ProductGroupName == productGroupName && c.ProductTypeName == productTypeName
// insert dynamic filter here
orderby c.ProductTypeName
select c;
return q;
}
(source: scottgu.com)
You need something like this? Use the Linq Dynamic Query Library (download includes examples).
Check out ScottGu's blog for more examples.
I have similar scenario where I need to add filters based on the user input and I chain the where clause.
Here is the sample code.
var votes = db.Votes.Where(r => r.SurveyID == surveyId);
if (fromDate != null)
{
votes = votes.Where(r => r.VoteDate.Value >= fromDate);
}
if (toDate != null)
{
votes = votes.Where(r => r.VoteDate.Value <= toDate);
}
votes = votes.Take(LimitRows).OrderByDescending(r => r.VoteDate);
You can also use the PredicateBuilder from LinqKit to chain multiple typesafe lambda expressions using Or or And.
http://www.albahari.com/nutshell/predicatebuilder.aspx
A simple Approach can be if your Columns are of Simple Type like String
public static IEnumerable<MyObject> WhereQuery(IEnumerable<MyObject> source, string columnName, string propertyValue)
{
return source.Where(m => { return m.GetType().GetProperty(columnName).GetValue(m, null).ToString().StartsWith(propertyValue); });
}
It seems much simpler and simpler to use the ternary operator to decide dynamically if a condition is included
List productList = new List();
productList =
db.ProductDetail.Where(p => p.ProductDetailID > 0 //Example prop
&& (String.IsNullOrEmpty(iproductGroupName) ? (true):(p.iproductGroupName.Equals(iproductGroupName)) ) //use ternary operator to make the condition dynamic
&& (ID == 0 ? (true) : (p.ID == IDParam))
).ToList();
I came up with a solution that even I can understand... by using the 'Contains' method you can chain as many WHERE's as you like. If the WHERE is an empty string, it's ignored (or evaluated as a select all). Here is my example of joining 2 tables in LINQ, applying multiple where clauses and populating a model class to be returned to the view. (this is a select all).
public ActionResult Index()
{
string AssetGroupCode = "";
string StatusCode = "";
string SearchString = "";
var mdl = from a in _db.Assets
join t in _db.Tags on a.ASSETID equals t.ASSETID
where a.ASSETGROUPCODE.Contains(AssetGroupCode)
&& a.STATUSCODE.Contains(StatusCode)
&& (
a.PO.Contains(SearchString)
|| a.MODEL.Contains(SearchString)
|| a.USERNAME.Contains(SearchString)
|| a.LOCATION.Contains(SearchString)
|| t.TAGNUMBER.Contains(SearchString)
|| t.SERIALNUMBER.Contains(SearchString)
)
select new AssetListView
{
AssetId = a.ASSETID,
TagId = t.TAGID,
PO = a.PO,
Model = a.MODEL,
UserName = a.USERNAME,
Location = a.LOCATION,
Tag = t.TAGNUMBER,
SerialNum = t.SERIALNUMBER
};
return View(mdl);
}
Just to share my idea for this case.
Another approach by solution is:
public IOrderedQueryable GetProductList(string productGroupName, string productTypeName, Dictionary> filterDictionary)
{
return db.ProductDetail
.where
(
p =>
(
(String.IsNullOrEmpty(productGroupName) || c.ProductGroupName.Contains(productGroupName))
&& (String.IsNullOrEmpty(productTypeName) || c.ProductTypeName.Contains(productTypeName))
// Apply similar logic to filterDictionary parameter here !!!
)
);
}
This approach is very flexible and allow with any parameter to be nullable.
You could use the Any() extension method. The following seems to work for me.
XStreamingElement root = new XStreamingElement("Results",
from el in StreamProductItem(file)
where fieldsToSearch.Any(s => el.Element(s) != null && el.Element(s).Value.Contains(searchTerm))
select fieldsToReturn.Select(r => (r == "product") ? el : el.Element(r))
);
Console.WriteLine(root.ToString());
Where 'fieldsToSearch' and 'fieldsToReturn' are both List objects.
This is the solution I came up with if anyone is interested.
https://kellyschronicles.wordpress.com/2017/12/16/dynamic-predicate-for-a-linq-query/
First we identify the single element type we need to use ( Of TRow As DataRow) and then identify the “source” we are using and tie the identifier to that source ((source As TypedTableBase(Of TRow)). Then we must specify the predicate, or the WHERE clause that is going to be passed (predicate As Func(Of TRow, Boolean)) which will either be returned as true or false. Then we identify how we want the returned information ordered (OrderByField As String). Our function will then return a EnumerableRowCollection(Of TRow), our collection of datarows that have met the conditions of our predicate(EnumerableRowCollection(Of TRow)). This is a basic example. Of course you must make sure your order field doesn’t contain nulls, or have handled that situation properly and make sure your column names (if you are using a strongly typed datasource never mind this, it will rename the columns for you) are standard.
System.Linq.Dynamic might help you build LINQ expressions at runtime.
The dynamic query library relies on a simple expression language for formulating expressions and queries in strings.
It provides you with string-based extension methods that you can pass any string expression into instead of using language operators or type-safe lambda extension methods.
It is simple and easy to use and is particularly useful in scenarios where queries are entirely dynamic, and you want to provide an end-user UI to help build them.
Source: Overview in Dynamic LINQ
The library lets you create LINQ expressions from plain strings, therefore, giving you the possibility to dynamically build a LINQ expression concatenating strings as you require.
Here's an example of what can be achieved:
var resultDynamic = context.Customers
.Where("City == #0 and Age > #1", "Paris", 50)
.ToList();

Categories

Resources