Swapping list values using LINQ - c#

I want to swap the list as explained below. I want to retain the count of list with some element values(not all) to be swapped from 'primary' to 'secondary'.
namespace listswap
{
public class emp
{
public int id { get; set; }
public string primary { get; set; }
public string fName { get; set; }
public string lName { get; set; }
public string state { get; set; }
public string country { get; set; }
}
class Program
{
static void Main(string[] args)
{
var empList = new List<emp>();
empList.AddRange(new emp[] { new emp {primary = "Yes", id = 1, fName = "Vivek", lName = "Ranjan", state = "TN", country = "India"},
new emp { primary = "No", id = 2, fName = "Deepak", lName = "Kumar", state = "AP", country = "UK"},
});
/* Desired list :
No of list 1 with two elements
empList[0]. primary = "Yes", id = 1, fName = "Vivek", lName = "Ranjan", state = "TN", country = "India"
empList[1]. primary = "No", id = 2, fName = "Vivek", lName = "Ranjan", state = "TN", country = "India"
*/
}
}
}

This is basics and as simple as:
var l1 = empList.Where(c=>c.primary == "Yes").ToList();
var l2 = empList.Where(c=>c.primary == "No").ToList();
For list of lists:
var result = empList.GroupBy(c => c.primary).Select(c => c.ToList()).ToList();
EDIT:
var primary = empList.FirstOrDefault(c => c.primary == "Yes");
var r = empList.Select(c => new emp
{
primary = c.primary,
id = c.id,
fName = primary != null ? primary.fName : c.fName,
lName = primary != null ? primary.lName : c.lName,
state = primary != null ? primary.state : c.state,
country = primary != null ? primary.country : c.country
}).ToList();

Related

How can I join a list of employees and genders using linq

I have retrieve a list of employees. my employee class columns(employeeId, lastname, genderid)
List<m_employees> Items = new List<m_employees>
{
new m_employees{ employeeid = 1, lastname = "mike", genderid = 1 },
new m_employees{ employeeid = 2, lastname = "jeni", genderid = 2 }
};
then i have my gender class columns (id, title)
List<m_genders> genders = new List<m_genders>
{
new m_genders{ id = 1, title = "Male" },
new m_genders{ id = 2, title = "Female" }
};
//then i tried joining the retrieved list of employees to the genders
var x = from emp in Items
join sex in genders
on emp.genderid equals sex.id
into a from b in a.DefaultIfEmpty(new m_genders())
select new
{
emp.lastname,
emp.genderid,
sex = b.title
};
red error line is showing to the keyword join and says "the type of one of the expressions in the join clause is incorrect..."
how can i join them properly?
This happens because types emp.genderid, sex.id are different and you need to cast or convert them explicitly like that:
(int)emp.genderid equals sex.id
I was able to reproduce the error with the following class definition:
class m_genders
{
public int id { get; set; }
public string title { get; set; }
}
class employee
{
public int id;
public uint genderid;
public string lastname { get; set; }
}
Your question is not clear, the code work without any problem :
namespace WindowsFormsApp1
{
public class m_genders
{
public int id;
public string title;
}
public class m_employees
{
public int employeeid { get; set; }
public int genderid { get; set; }
public string lastname { get; set; }
}
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
List<m_genders> genders = new List<m_genders>
{
new m_genders {id = 1, title = "Male"},
new m_genders {id = 2, title = "Female"}
};
List<m_employees> Items = new List<m_employees>
{
new m_employees{ employeeid = 1, lastname = "mike", genderid = 1 },
new m_employees{ employeeid = 2, lastname = "jeni", genderid = 2 }
};
var x = from emp in Items
join sex in genders
on emp.genderid equals sex.id
into a
from b in a.DefaultIfEmpty(new m_genders())
select new
{
emp.lastname,
emp.genderid,
sex = b.title
};
}
}
}

How can I get latest employee ID (string) from the list of employees using .net web api Get call

I am using Entity Framework
My EmployeeDto class is :
public class EmployeeDto
{
[DataMember]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int SerialNumber { get; set; }
[DataMember]
[Key]
[Required]
public string ID { get; set; }
[DataMember]
[Required]
public string FirstName { get; set; }
[DataMember]
public string MiddleName { get; set; }
[DataMember]
[Required]
public string LastName { get; set; }
}
My Dto class is EmployeeDto and Dal class is named as Employee. I want to get the maximum value of EmployeeID from the database and provide it to frontend through Get call .
My Get call to get the list of all employees is :
public List<EmployeeDto> GetAllEmployees()
{
var employeeDto = new List<EmployeeDto>();
using (EmployeeDataEntities entities = new EmployeeDataEntities())
{
var employeeData = entities.Employees.ToList().Where(e => e.IsActive == true);
List<Employee> emp = employeeData.ToList();
//emp.FindLastIndex(e => e.)
employeeDto = Mapper.Map<List<Employee>,List<EmployeeDto>>(emp);
};
return employeeDto;
}
This is my GetLatestEmployeeByID code :
public int GetEmployeeLatestID(EmployeeDto employeeDto)
{
using (EmployeeDataEntities entities = new EmployeeDataEntities())
{
var employeeData = entities.Employees.ToList().Where(e => e.IsActive == true);
List<Employee> emp = employeeData.ToList();
emp.FindLastIndex(e => e.ID);
}
}
I have tried a couple of solutions and i end up with this one:
var a = new List<EmployeeDto>()
{
new EmployeeDto()
{
SerialNumber = 1,
ID = "AB01",
FirstName = "Ala",
MiddleName = "b",
LastName = "ala"
},
new EmployeeDto()
{
SerialNumber = 2,
ID = "AB02",
FirstName = "Ala",
MiddleName = "b",
LastName = "ala"
},new EmployeeDto()
{
SerialNumber = 3,
ID = "AB03",
FirstName = "Ala",
MiddleName = "b",
LastName = "ala"
}
};
// biggestIdAsInt = 230 a.max returns the max value after the calculations
var biggestIdAsInt = a.Max(employee => Encoding.ASCII.GetBytes(employee.ID) // get Employee Id as byte array
.Sum(b => b)); // summ the bytes for each employee
// 230
var substractedNumberFromBiggestId = Regex.Match(a.FirstOrDefault(x => x.ID.ToCharArray().Sum(y => y) == biggestIdAsInt).ID, #"\d+").Value;
Console.WriteLine(substractedNumberFromBiggestId);
I have put comments to make the code a little bit clearer.

Search by Single and multiple Key Words both from single textbox

var db = new MatriModel();
string s = txtKeyWord.Text;
string[] words = s.Split(',');
int count = words.Length;
if (count <= 5)
{
SerachByKeyWordPanel.Visible = true;
var KeyWord = db.tblProfiles.Where(x => words.Contains(x.tblCaste.Caste) && words.Contains(x.tblCountry.Country) && words.Contains(x.City) && words.Contains(x.tblOccupation.Occupation) && words.Contains(x.tblMotherTongue.MotherTongue)).Select(x => new
{
ProfileID = x.ProfileID,
ProfileFor = x.tblProfileFor.ProfileFor,
}.ToList();
By Above code I can get details for multiple keywords but at the same time, I want to get records by single keyword also.
Please some one help me, Thanks in Advance
See the following code snippet based on a simplified object:
class MatrixModel {
public string ProfileId {get; set;}
public string Caste {get; set;}
public string Country {get; set;}
public string City {get; set;}
public string Occupation {get; set;}
public string MotherTongue {get; set;}
}
public static void Main()
{
var db = new MatrixModel[]{
new MatrixModel {
ProfileId = "1",
Caste = "Caste1",
Country = "USA",
City = "Miami",
Occupation = "System administrator",
MotherTongue = "English"
},
new MatrixModel {
ProfileId = "2",
Caste = "Caste1",
Country = "India",
City = "Mumbai",
Occupation = "developer",
MotherTongue = "English"
},
new MatrixModel {
ProfileId = "3",
Caste = "Caste1",
Country = "England",
City = "London",
Occupation = "developer",
MotherTongue = "English"
},
};
string s = "Caste1, England";
string[] words = s.Split(',');
int count = words.Length;
if (count <= 5)
{
IEnumerable<MatrixModel> KeyWord = db;
foreach(var par in words)
{
var parTrimmed = par.Trim();
KeyWord = KeyWord
.Where(x => x.Caste == parTrimmed
|| x.Country == parTrimmed
|| x.City == parTrimmed
|| x.Occupation == parTrimmed
|| x.MotherTongue == parTrimmed);
}
var result = KeyWord.Select(x => new
{
ProfileID = x.ProfileId,
}).ToList();
foreach(var item in result){
Console.WriteLine(item);
}
}
}
The result is the following:
{ ProfileID = 3 }

Two tables deep left outer join

I have the following query and I am getting a null reference exception:
(from cec in _myContext.table1s
join ceclrp in _myContext.table2s on cec.table1ID equals ceclrp.table1ID
join lrp in _myContext.table3s on ceclrp.table3ID equals lrp.table3ID
join cecs in _myContext.table4s on cec.table1ID equals cecs.table1ID into cecsGroup
from ecService in cecsGroup.DefaultIfEmpty()
join cecse in _myContext.table5s on ecService.table4ID equals cecse.table4ID into cecseGroup
from ecServiceEntitlement in cecseGroup.DefaultIfEmpty()
where cec.ClientKey == clientKey
select new
{
table1 = cec,
table2 = ceclrp,
table3 = lrp,
table4 = ecService,
table5 = ecServiceEntitlement,
}).AsNoTracking();
Table 1, 2, and 3 records are required tables. However table 4 record is optional. If there is a table 4 record, then there can be an optional table 5 record.
However, I am getting a null reference exception when there is no table 4 or table 5 record.
I have looked at other questions similar to mine on StackOverflow but I can't figure out what is different from my query and the solutions posted.
Can someone please help me figure out why I am getting the null reference exception and what I need to do differently?
According to MSDN,
The default value for reference and nullable types is null.
For more than one LEFT JOIN, we can handle the null value by passing defaultValue for the DefaultIfEmpty() extension method. The following sample code works when I pass the default Constructor new Driver(), it throws exception if the defaultValue is removed.
Here I have created three models (Dealer, Model and Customer) with matching records and two models (Driver, DriverAddress) with optional records. The same as OP scenario.
So, passing the default value for the first LEFT JOIN may solve your problem.
public class Dealer
{
public int DealerId { get; set; }
public string Name { get; set; }
}
public class Model
{
public int ModelId { get; set; }
public string Name { get; set; }
public Dealer Dealer { get; set; }
}
public class Customer
{
public int CustomerId { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public Model Model { get; set; }
}
public class Driver
{
public int DriverId { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public Customer Customer { get; set; }
}
public class DriverAddress
{
public int DriverAddressId { get; set; }
public string AddressLine1 { get; set; }
public string AddressLine2 { get; set; }
public string City { get; set; }
public string Zip { get; set; }
public Driver Driver { get; set; }
}
class Program
{
static void Main(string[] args)
{
var honda = new Dealer { DealerId = 1, Name = "Honda" };
var ford = new Dealer { DealerId = 2, Name = "Ford" };
var toyoto = new Dealer { DealerId = 3, Name = "Toyoto" };
var volkswagen = new Dealer { DealerId = 4, Name = "Volkswagen" };
var chevrolet = new Dealer { DealerId = 5, Name = "Chevrolet" };
var civic = new Model { ModelId = 1, Name = "Civic", Dealer = honda };
var fiesta = new Model { ModelId = 2, Name = "Fiesta", Dealer = ford };
var corolla = new Model { ModelId = 3, Name = "Corolla", Dealer = toyoto };
var passat = new Model { ModelId = 4, Name = "Passat", Dealer = volkswagen };
var cruze = new Model { ModelId = 5, Name = "Cruze", Dealer = chevrolet };
var magnus = new Customer { CustomerId = 1, FirstName = "Magnus", LastName = "Hedlund", Model = civic };
var terry = new Customer { CustomerId = 2, FirstName = "Terry", LastName = "Adams", Model = fiesta };
var charlotte = new Customer { CustomerId = 3, FirstName = "Charlotte", LastName = "Weiss", Model = corolla };
var john = new Customer { CustomerId = 4, FirstName = "John", LastName = "Miller", Model = passat };
var arlene = new Customer { CustomerId = 5, FirstName = "Arlene", LastName = "Huff", Model = cruze };
var driver1 = new Driver { DriverId = 1, FirstName = "Fadi", LastName = "Fakhouri", Customer = magnus };
var driver2 = new Driver { DriverId = 2, FirstName = "Hanying", LastName = "Feng", Customer = terry };
var driver3 = new Driver { DriverId = 3, FirstName = "Cesar", LastName = "Garcia", Customer = charlotte };
var driver4 = new Driver { DriverId = 4, FirstName = "Lint", LastName = "Tucker", Customer = magnus };
var driver5 = new Driver { DriverId = 5, FirstName = "Robert", LastName = "Thomas", Customer = arlene };
var driver6 = new Driver { DriverId = 6, FirstName = "David", LastName = "Adams", Customer = charlotte };
var driver1Address = new DriverAddress { DriverAddressId = 1, AddressLine1 = "Main St", City = "Minnehaha", Zip = "57105", Driver = driver1 };
var driver2Address = new DriverAddress { DriverAddressId = 2, AddressLine1 = "State St", City = "Los Angeles", Zip = "90034", Driver = driver2 };
var driver3Address = new DriverAddress { DriverAddressId = 3, AddressLine1 = "Ralph St", City = "Winnebago", Zip = "61109", Driver = driver4 };
List<Dealer> lstDealers = new List<Dealer> { honda, ford, toyoto, volkswagen, chevrolet };
List<Model> lstModels = new List<Model> { civic, fiesta, corolla, passat, cruze };
List<Customer> lstCustomers = new List<Customer> { magnus, terry, charlotte, john, arlene };
List<Driver> lstDrivers = new List<Driver> { driver1, driver2, driver3, driver4, driver5, driver6 };
List<DriverAddress> lstDriverAddress = new List<DriverAddress> { driver1Address, driver2Address, driver3Address };
var result = from dealer in lstDealers
join model in lstModels on dealer.DealerId equals model.Dealer.DealerId
join customer in lstCustomers on model.ModelId equals customer.Model.ModelId
join driver in lstDrivers on customer.CustomerId equals driver.Customer.CustomerId into customerDriverGroup
from customerDriver in customerDriverGroup.DefaultIfEmpty(new Driver()) //defaultValue the empty constructor passed here
join address in lstDriverAddress on customerDriver.DriverId equals address.Driver.DriverId into driverAddressGroup
from driverAddress in driverAddressGroup.DefaultIfEmpty()
select new
{
Dealer = dealer,
Model = model,
Customer = customer,
Driver = customerDriver,
DriverAddress = driverAddress
};
foreach (var v in result)
{
Console.WriteLine("{0,-15}{1,-15}{2,-15}{3,-15}{4}", v.Dealer.Name + ":",
v.Model.Name + ":", v.Customer.FirstName + ":", v.Driver == null ? String.Empty : v.Driver.FirstName
+ ":", v.DriverAddress == null ? string.Empty : v.DriverAddress.City);
}
Console.Read();
}
}
You should check if your select new {... } values are null
Like:
select new
{
table1 = cec,
table2 = ceclrp,
table3 = lrp,
table4 = (ecService == null ? string.Empty : ecService),
table5 = (ecServiceEntitlement == null ? string.Empty : ecServiceEntitlement),
}).AsNoTracking();
This might be the problem.
join cecse in _myContext.table5s on ecService.table4ID equals cecse.table4ID into cecseGroup
When ecService == null, ecService .table4ID will cause a Null reference exception
Can you try this instead.
join cecse in _myContext.table5s on (ecService == null? 0 : ecService.table4ID) equals cecse.table4ID into cecseGroup
you can change 0 to any integer value which is not used in _myContext.table4s.table4ID. So your query would look like this.
(from cec in _myContext.table1s
join ceclrp in _myContext.table2s on cec.table1ID equals ceclrp.table1ID
join lrp in _myContext.table3s on ceclrp.table3ID equals lrp.table3ID
join cecs in _myContext.table4s on cec.table1ID equals cecs.table1ID into cecsGroup
from ecService in cecsGroup.DefaultIfEmpty()
join cecse in _myContext.table5s on (ecService == null? 0 : ecService.table4ID) equals cecse.table4ID into cecseGroup
from ecServiceEntitlement in cecseGroup.DefaultIfEmpty()
where cec.ClientKey == clientKey
select new
{
table1 = cec,
table2 = ceclrp,
table3 = lrp,
table4 = ecService,
table5 = ecServiceEntitlement,
}).AsNoTracking();
I would just expand the cecse variable into a left outer join too. Like how we would have done it in raw SQL too.
(from cec in _myContext.table1s
join ceclrp in _myContext.table2s on cec.table1ID equals ceclrp.table1ID
join lrp in _myContext.table3s on ceclrp.table3ID equals lrp.table3ID
join cecs in _myContext.table4s on cec.table1ID equals cecs.table1ID into cecsGroup
from ecService in cecsGroup.DefaultIfEmpty()
from cecse in _myContext.table5s.DefaultIfEmpty() // <---- here
from ecServiceEntitlement in cecseGroup.DefaultIfEmpty()
where cec.ClientKey == clientKey
&& ecService.table4ID equals cecse.table4ID // <---- here
select new
{
table1 = cec,
table2 = ceclrp,
table3 = lrp,
table4 = ecService,
table5 = ecServiceEntitlement,
}).AsNoTracking();

Linq : Comparing 1 Child Collection to (Aggregated) ChildCollection(s)

I have a Linq question: (DotNet Framework 4.0)
I have the following classes:
public class Employee
{
public Guid? EmployeeUUID { get; set; }
public string SSN { get; set; }
}
public class JobTitle
{
public Guid? JobTitleSurrogateKey { get; set; }
public string JobTitleName { get; set; }
}
public class EmployeeToJobTitleMatchLink
{
public EmployeeToJobTitleMatchLink()
{
this.TheJobTitle = new JobTitle() { JobTitleSurrogateKey = Guid.NewGuid(), JobTitleName = "SomeJobTitle:" + Guid.NewGuid().ToString("N") };
}
public Guid LinkSurrogateKey { get; set; }
/* Related Objects */
public Employee TheEmployee { get; set; }
public JobTitle TheJobTitle { get; set; }
}
public class Organization
{
public Organization()
{
this.Links = new List<EmployeeToJobTitleMatchLink>();
}
public int OrganizationSurrogateKey { get; set; }
public ICollection<EmployeeToJobTitleMatchLink> Links { get; set; }
}
In my code below, I can compare 2 child-collections and get the results I need (in "matches1".
Here I am using the "SSN" string property to compare and find the overlaps. And the Console.Write for matches1 works as I expect.
What I don't know how to do is compare the first child collection (org10) to all the children in (allOtherOrgsExceptOrg10 (all the Organizations and all the Links of these Organizations )
The commented out code shows kinda what I'm trying to do, one of my many feeble attempts today.
But basically, match2 would be populated with all the SSN overlaps...but comparing org10 with allOtherOrgsExceptOrg10, all their "Links", and their Employee.SSN's.
org10 overlaps with org20 with "AAA", so match2 would contain "AAA". and org10 overlaps with org30 with "BBB" so match2 would contain "BBB".
Organization org10 = new Organization();
org10.OrganizationSurrogateKey = 10;
Employee e11 = new Employee() { SSN = "AAA", EmployeeUUID = new Guid("AAAAAAAA-AAAA-AAAA-AAAA-AAAAAAAAAAAA") };
EmployeeToJobTitleMatchLink link11 = new EmployeeToJobTitleMatchLink();
link11.TheEmployee = e11;
org10.Links.Add(link11);
Employee e12 = new Employee() { SSN = "BBB", EmployeeUUID = new Guid("BBBBBBBB-BBBB-BBBB-BBBB-BBBBBBBBBBBB") };
EmployeeToJobTitleMatchLink link12 = new EmployeeToJobTitleMatchLink();
link12.TheEmployee = e12;
org10.Links.Add(link12);
Organization org20 = new Organization();
org20.OrganizationSurrogateKey = 20;
Employee e21 = new Employee() { SSN = "AAA", EmployeeUUID = new Guid("AAAAAAAA-AAAA-AAAA-AAAA-AAAAAAAAAAAA") };
EmployeeToJobTitleMatchLink link21 = new EmployeeToJobTitleMatchLink();
link21.TheEmployee = e21;
org20.Links.Add(link21);
Employee e22 = new Employee() { SSN = "CCC", EmployeeUUID = new Guid("CCCCCCCC-CCCC-CCCC-CCCC-CCCCCCCCCCCC") };
EmployeeToJobTitleMatchLink link22 = new EmployeeToJobTitleMatchLink();
link22.TheEmployee = e22;
org20.Links.Add(link22);
Organization org30 = new Organization();
org30.OrganizationSurrogateKey = 30;
Employee e31 = new Employee() { SSN = "BBB", EmployeeUUID = new Guid("BBBBBBBB-BBBB-BBBB-BBBB-BBBBBBBBBBBB") };
EmployeeToJobTitleMatchLink link31 = new EmployeeToJobTitleMatchLink();
link31.TheEmployee = e31;
org30.Links.Add(link31);
Employee e32 = new Employee();
e32.SSN = "ZZZ";
EmployeeToJobTitleMatchLink link32 = new EmployeeToJobTitleMatchLink();
link32.TheEmployee = e32;
org30.Links.Add(link32);
IList<Organization> allOtherOrgsExceptOrg10 = new List<Organization>();
/* Note, I did not add org10 here */
allOtherOrgsExceptOrg10.Add(org20);
allOtherOrgsExceptOrg10.Add(org30);
IEnumerable<EmployeeToJobTitleMatchLink> matches1 =
org10.Links.Where(org10Link => org20.Links.Any(org20Link => org20Link.TheEmployee.SSN.Equals(org10Link.TheEmployee.SSN, StringComparison.OrdinalIgnoreCase)));
IEnumerable<EmployeeToJobTitleMatchLink> matches2 = null;
//org10.Links.Where(org10Link => ( allOtherOrgs.Where ( anyOtherOrg => anyOtherOrg.Links.Any(dbSideChild => dbSideChild.TheEmployee.SSN == org10Link.TheEmployee.SSN)) );
if (null != matches1)
{
foreach (EmployeeToJobTitleMatchLink link in matches1)
{
Console.WriteLine(string.Format("matches1, SSN = {0}", link.TheEmployee.SSN));
}
}
if (null != matches2)
{
foreach (EmployeeToJobTitleMatchLink link in matches2)
{
Console.WriteLine(string.Format("matches2, SSN = {0}", link.TheEmployee.SSN));
}
}
matches2 =
allOtherOrgsExceptOrg10.SelectMany(x => x.Links)
.Where(x => org10.Links.Select(o => o.TheEmployee.SSN).Contains(x.TheEmployee.SSN));
You can use the SelectMany on the allOther collection to select all Links over all org's. Then check if any SSN is inside the org10 List.
See: http://msdn.microsoft.com/en-us/library/system.linq.enumerable.selectmany(v=vs.100).aspx
You can use SelectMany to flatten out the collection and then use it just like you have for matches1
IEnumerable<EmployeeToJobTitleMatchLink> matches2 =
org10.Links.Where(
org10Link =>
allOtherOrgsExceptOrg10.SelectMany(allOtherOrgs => allOtherOrgs.Links).Any(
anyOtherLink =>
anyOtherLink.TheEmployee.SSN.Equals(org10Link.TheEmployee.SSN, StringComparison.OrdinalIgnoreCase)));
The SelectMany will make it seem like one IEnumerable instead of and IEnumerable of an IEnumerable.

Categories

Resources