I have an IQueryable collection of Employee objects which has FirstName, LastName, Department in it. I'm passing a string of LastName separated by comma. I want to use where clause to filter data which has LastName selected as "Sharma,Gupta". Can someone help me out?
Employee class
public class Employee
{
public string FirstName { get; set; }
public string LastName { get; set; }
public string Department { get; set; }
public string EmpID { get; set; }
}
public IQueryable<Employee> GetEmpData(String filterExpression)
{
IQueryable<Employee> data = GetEmployeeData();
data = from da in data
where (da.LastName == "Sharma")
select da;
return data;
}
In the above method I can query a single value. filterExpression contains list of LastName separated by a comma. Can someone guide me how to use filterExpression in where clause?
Split your string and use .Contains:
names = filterExpression.Split(",");
IQueryable<Employee> data = GetEmployeeData();
data = from da in data
where names.Contains(da.LastName)
select da;
As you return the entire object and do not project only parts of it using the method syntax might be more readable:
return GetEmployeeData().Where(item => names.Contains(item.LastName));
If your filterExpression is a string, with the names separated by commas, then you'd want to change your query to check if the last name is in the list of names in filterExpression like this:
public IQueryable<Employee> GetEmpData(String filterExpression)
{
List<string> names = filterExpression.Split(",");
return GetEmployeeData().Where(names.Contains(da.LastName));
}
Related
I am trying to retrieve data from mysql database using dapper but the result sets id (primary key) and foreign key as nulls. Other attributes have values.
I tried to change sql query from select * from courses to full form as select id,name,did from courses.
Course{
public Course()
{
}
public string Id { get; set; }
public string Title { get; set; }
public int Credits { get; set; }
public bool Is_Elective { get; set; }
public string DId { get; set; }
public int Sem { get; set; }
}
class CourseDAO
{
private readonly MySqlConnection conn;
private string connectionString = "Server=localhost;Database=university;Uid=root;Pwd=*****;";
public CourseDAO()
{
conn = new MySqlConnection(connectionString);
}
public List<Course> getAll()
{
string sql = "select * from university.course";
List<Course> courses = conn.Query<Course>(#sql).ToList();
return courses;
}
}
Expected:
Courses list have all courses from db with correct values.
Actual
Courses list has all courses from db with id and did as null and rest have values.
Even if issue was solved in question comments by Maxim, I'd like to describe problem with few solution alternatives.
Problem cause:
Dapper executes mapping from sql query result to object by name. Sql query result field 'title' is automatically mapped to Course.Title (mapping is case-insensitive).
In your case there was two name-mismatches between db columns vs. C# properties: (course_id != Id and department_id != DId), therefore Dapper was unable to map those fields.
Solution 1, sql column aliases
You can list table columns with possible columns aliases in sql query following way:
string sql = "select course_id Ad Id, title, credits, Is_elective, department_id as DId, sem from university.course";
Using explicit column names in sql, Dapper can execute automatic name-based mappings.
Solution 2, Dapper custom mappings
Dapper Custom mapping is the feature to manually define, for each object, which column is mapped to which property.
Here is class which deal with the mappings (idea for this both-ways mapping borrowed from another SO answer):
public class ColumnMap
{
private readonly Dictionary<string, string> mappings = new Dictionary<string, string>();
public void Add(string t1, string t2)
{
mappings.Add(t1, t2);
}
public string this[string index]
{
get
{
// Check for a custom column map.
if (forward.ContainsKey(index))
return forward[index];
if (reverse.ContainsKey(index))
return reverse[index];
// If no custom mapping exists, return the value passed in.
return index;
}
}
}
Setup the ColumnMap object and tell Dapper to use the mapping.
var columnMap = new ColumnMap();
columnMap.Add("Id", "course_id");
columnMap.Add("DId", "department_id");
SqlMapper.SetTypeMap(typeof (Course), new CustomPropertyTypeMap(typeof (Course), (type, columnName) => type.GetProperty(columnMap[columnName])));
Solution 3, dynamic type and LINQ
You can execute field mapping using dynamic object as following:
string sql = "select * from university.course";
List<Course> courses = conn.Query<dynamic>(#sql)
.Select(item => new Course()
{
Id = item.course_id,
Title = item.title,
Credits = item.credits,
Is_Elective = item.Is_elective,
DId = department_id,
Sem = sem
})
.ToList();
I'm new to Linq but need to get some code finished quickly. I have two classes:
public class SAPMember
{
public string EmployeeNumber { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public List<CostCentre> CostCentres { get; set; }
}
public class CostCentre
{
public string EmployeeNumber { get; set; }
public string CostCentreCode { get; set; }
public string Division { get; set; }
}
Each SAPMember can have one or more CostCentres.
This is my code to populate a two independent lists initially (using Dapper), which I then hope to combine into one list with a sublist:
_SAPMembers = new List<SAPMember>();
string sql = #"SELECT EmployeeNo as EmployeeNumber,
LastName, FirstName
FROM Employees";
_SAPMembers = DbConn.Query<SAPMember>(sql).ToList();
List<CostCentre> _CostCentres = new List<CostCentre>();
string sql2 = #"SELECT EmployeeNo as EmployeeNumber, CostCentreCode,
DivisionDescription as Division
FROM Employees";
_CostCentres = DbConn.Query<CostCentre>(sql2).ToList();
I've tried Linq grouping and joins etc but can't get the syntax right, and my _SAPMembers list populated with employee details plus related list of costcentres.
Code sample would be greatly appreciated. I've seen that this might be possible from one more complex Dapper query, but I think for my skill level linq might be a better solution.
As Amit suggested, I could use Dapper, as so: (note:I changed CostCentre key to EmpNo)
if (_SAPMembers == null)
{
List _SAPMembers = new List();
var lookup = new Dictionary<string, SAPMember>();
var result = DbConn.Query<SAPMember, CostCentre, SAPMember>(#"
select DISTINCT e.EmployeeNo as EmployeeNumber, e.LastName, e.FirstName, c.EmployeeNo as EmpNo
, c.CostCentreCode as Name, c.DivisionDescription as Division
FROM EmployeeListing e
join EmployeeListing c on e.EmployeeNo = c.EmployeeNo
where e.TerminationDate is null and c.TerminationDate is null", (e, c) =>
{
if (!lookup.TryGetValue(e.EmployeeNumber, out SAPMember sapMember))
lookup.Add(e.EmployeeNumber, sapMember = e);
if (sapMember.CostCentres == null)
sapMember.CostCentres = new List<CostCentre>();
sapMember.CostCentres.Add(c);
return sapMember;
}, splitOn: "EmpNo");
_SAPMembers = result.Distinct().ToList();
}
return _SAPMembers;
I am using the following query. It returns 5 rows in a list but all the elements in the list are null.
public class TempClass
{
public int SID { get; set; }
public string SNAME { get; set; }
public string SAGE { get; set; }
}
var i = _dbContext.Database
.SqlQuery<TempClass>("select ID, NAME, AGE from eis_hierarchy")
.ToList();
What I am doing wrong?
Try making the columns returned in the SQL query match the property names in the class you're trying to return:
var i = _dbContext.Database
.SqlQuery<TempClass>("select ID as SID, NAME as SNAME, AGE as SAGE from eis_hierarchy")
.ToList();
I have to select multiple columns from a database and I don't have a matching entity.
so my query looks like this:
var result = _dbContext.Database.SqlQuery<List<string>>(
"select ID, NAME, DB_FIELD from eis_hierarchy");
I am getting the result set, each row contains list of strings but count is 0.
So how do I select multiple columns using Database.SqlQuery?
You have to capture the results into a class with matching property names, and (at least) a parameterless constructor:
class DbResult
{
public int ID { get; set; }
public string NAME { get; set; }
public string DB_FIELD { get; set; }
}
var result = _dbContext.Database.SqlQuery<DbResult>(
"select ID, NAME, DB_FIELD from eis_hierarchy");
I am a beginner to dapper . I was going through the code and building samples . But I am having problems in retrieving data .
My code is as follows
Console.WriteLine("Reading Values");
string readSatement = "select * from employee where Id=#Id ";
IEnumerable<Employee> objEmp1 = con.Query<Employee>(readSatement,
new {
Id = empId
});
var objEmp2 = con.Query(readSatement, new { Id = empId });
In this code objEmp2 retrieves values from db for the id passed . But objEmp1 gives null values for the attributes of the object .
Employee class is as below
public class Employee
{
public int EmpId { get; set; }
public string EmpName { get; set; }
public int EmpAge { get; set; }
}
Whats wrong with the code .
You need to ensure all your database columns either match the properties in your class you are using for the query or you return the columns with names that match. For example in your query above, I believe you might want to write it like:
select Id as EmpId, otherColumn as Propertyname, etc.. from employee
where Id = #Id