Sort a list using a search string - c#

I am trying to sort a list on the basis of a search string. But there seems to be some issue.
Below is the code:
namespace ListDemo
{
class Program
{
static void Main(string[] args)
{
Employee e1 = new Employee {ID=1,Name="John",City="London" };
Employee e2 = new Employee { ID = 2, Name = "Mary", City = "NY" };
Employee e3 = new Employee { ID = 3, Name = "Dave", City = "Sydney" };
Employee e4 = new Employee { ID = 4, Name = "Kate", City = "Chicago" };
Employee e5 = new Employee { ID = 5, Name = "Sheela", City = "Delhi" };
List<Employee> listEmployee = new List<Employee>();
listEmployee.Add(e1);
listEmployee.Add(e2);
listEmployee.Add(e3);
listEmployee.Add(e4);
listEmployee.Add(e5);
Console.WriteLine("Enter the name via which you wana sort?");
string searchString = Console.ReadLine();
Console.WriteLine("####################Sorted List Starts##############");
var items = from element in listEmployee
orderby element.Name.Equals(searchString)
select element;
foreach (var i in items)
{
Console.WriteLine(i.Name);
}
Console.ReadLine();
}
}
class Employee
{
public int ID { get; set; }
public string Name { get; set; }
public string City { get; set; }
}
}
I have an Employee class with 3 public properties, ID, Name and City.
I created a list of Employees with some dummy data in it.
Now I want the user to enter a search string, which will actually be a name, and if the list contains that name, it should sort the list as according to the search string.
For ex: if a user has entered name as 'John', then the revised list should show John as first item and so on.
The code which I have written behaves abnormally.
Image is attached:

Firstly, sort by equals in descending order (it means, that it will be firt in result), and others sort by ID to save original order (or, you can use any other property for ordering):
var items = listEmployee
.OrderByDescending(e => e.Name.Equals(searchString))
.ThenBy(e => e.ID).ToArray();

Related

How to join 2 entities to get translated text in Entity Framework 6

I'm using EF 6 Code-First and I want my costumers to introduce new records in multiple languages. To store this I save all the texts in a Dictionary entity with a custom key and reference it from my other entity through this key.
This is a basic sample of my entities:
Dictionary
ID Key IsoCode Value
1 firstEntry en-US My new entry
2 secondEntry en-US My second entry
3 firstEntry es-ES Mi nueva entrada
Entries
ID Name CreationDate
1 firstEntry 2020-11-04
2 secondEntry 2020-11-07
What I want to achieve is to query the Entries entity with an ISO Code, and get a new Entity where the Name field is replaced with Value field from the Dictionary entity.
This is what I have right now:
public List<Entry> GetEntries(string isoCode)
{
var query = (from e in dbContext.Entry
join d in dbContext.Dictionary on e.Name equals d.Key
where d.IsoCode == isoCode
select new
{
entry= e,
Text = d.Value
}).ToList();
return query.Select(t => new Entry
{
Id = t.entry.Id,
Name = t.Text,
CreationDate = t.CreationDate
}).ToList();
}
Is there a better way to do this without creating two lists?
Is this approach of using a Key to get translated text a best practice or am I missing the point here?
Here's a working example of your code using 2 lists instead of your tables (of course).
You can simply create the Entry in the first query. You don't need the .ToList() in that routine. Just return the IEnumerable.
using System;
using System.Collections.Generic;
using System.Linq;
namespace JoinEntities
{
class Program
{
static List<Dict> dictionary = new List<Dict>
{
new Dict
{
ID = 1,
Key = "firstEntry",
IsoCode = "en-US",
Value = "My new entry"
},
new Dict
{
ID = 2,
Key = "secondEntry",
IsoCode = "en-US",
Value = "My second entry"
},
new Dict
{
ID = 3,
Key = "firstEntry",
IsoCode = "es-ES",
Value = "Mi nueva entrada"
},
};
static List<Entry> entries = new List<Entry>
{
new Entry
{
Id = 1,
Name = "firstEntry",
CreationDate = new DateTime(2020, 11, 04)
},
new Entry
{
Id = 1,
Name = "secondEntry",
CreationDate = new DateTime(2020, 11, 07)
}
};
static void Main(string[] args)
{
var list = GetEntries("en-US");
}
public static IEnumerable<Entry> GetEntries(string isoCode)
{
return from e in entries
join d in dictionary on e.Name equals d.Key
where d.IsoCode == isoCode
select new Entry
{
Id = e.Id,
Name = d.Value,
CreationDate = e.CreationDate
};
}
}
internal class Dict
{
public int ID { get; set; }
public string Key { get; set; }
public string IsoCode { get; set; }
public string Value { get; set; }
}
internal class Entry
{
public object Id { get; set; }
public object Name { get; set; }
public object CreationDate { get; set; }
}
}

Linq query- Collection within a dictonary

I am trying to get result from a dictionary using linq but I am not sure how to do it.
I am trying to write a linq query to get the employee name,salary of the empId=2. Please correct me with the right linq query.
class Program
{
static void Main(string[] args)
{
Dictionary<int, List<Employee>> empDic = new Dictionary<int, List<Employee>>();
var emp = new List<Employee>();
emp.Add(new Employee{EmpID = 1,Name="affsa",Salary=2000}) ;
emp.Add(new Employee { EmpID = 2, Name = "axy",Salary=3000 });
emp.Add(new Employee { EmpID = 3, Name = "xyz",Salary=4000 });
empDic.Add(1,emp);
var selectedEmpDetails = empDic.Values
.Select(r => r.Where(f => f.EmpID ==2))
.ToList();
}
}
public class Employee
{
public string Name { get; set; }
public int EmpID { get; set; }
public int Salary { get; set; }
}
You could try something like this:
var selectedEmpDetails = empDic.SelectMany(x=>x.Value)
.Where(x=>x.EmpId==2)
.Select(x=> new { Name = x.Name, Salary = x.Salary });
Initially we flatten the values of the dictionary in a list of Employee objects.
Then we select the object with the EmpId equals to 2.
Last we select it's name and salary properties.
I would use SelectMany() function in your case so that I get a flattened list of Employee instances. Then try to get the first Employee instance that matches the employee id (if any) with the FirstOrDecault() function.
var selectedEmpDetails = empDic.Values.SelectMany(r => r.Where(f => f.EmpID == 2)).FirstOrDefault();
if(selectedEmpDetails != null)
{
string employeeName = selectedEmpDetails.Name;
int employeeSalary = selectedEmpDetails.Salary;
}

LinQ nested lists and nested selects

Consider these two tables:
ClassID Name
1 C1
2 C2
ClassID List<CourseSession>
1 [Object that has value "A"], [Object that has value "B"]
2 [Object that has value "B"], [Object that has value "C"]
When I join these two tables in Linq, I get:
ID Name List
1 C1 [A, B]
2 C2 [A, B]
Wheras I need to expand them:
ID Name List
1 C1 A
1 C1 B
2 C2 A
2 C2 B
Linq code:
var classes = from row in t.AsEnumerable()
select new
{
ClassID = row.Field<Guid>("ClassID"),
ClassName = row.Field<string>("Name"),
};
var classCourses = from row in classes.AsEnumerable()
select new
{
ID = row.ID,
CourseSessionList = GetAllCoursesByID(row.ID).AsEnumerable()
};
//Attempt to join
var expandedClassCourse = from classRow in classes
join ccRow in classCourses
on classRow.ID equals ccRow.ID
into filteredExpandedClasses
select filteredExpandedClasses;
I'm not sure how to achieve this. Any ideas?
Something like (not sure what your model looks like):
context.CouseSessions.Where(cs => /* condition goes here */)
.Select(cs =>
new
{
Name = cs.Name,
Class = cs.Class.Name
});
or
context.Classes.Where(c => /* condition goes here */)
.SelectMany(c => c.Courses)
.Select(cs =>
new
{
Name = cs.Name,
Class = cs.Class.Name
});
I created two models based on assumption. I hope this helps.
class Info
{
public int Id { get; set; }
public string Name { get; set; }
public List<string> List { get; set; }
}
class MyClass
{
public int Id { get; set; }
public string Name { get; set; }
public string s { get; set; }
}
static void Main(string[] args)
{
var infos = new List<Info> { new Info { Id = 1, Name = "c1", List = new List<string> { "A", "B" } }, new Info { Id = 2, Name = "c2", List = new List<string> { "A", "B" } } };
var myClasses = new List<MyClass>();
foreach (var info in infos)
{
myClasses.AddRange(info.List.Select(a => new MyClass { Id = info.Id, Name = info.Name, s = a }));
}
}
(from c in classList
join s in sessionList on c.ClassID equals s.ClassID
select new
{
ID = c.ClassID,
Name = c.Name,
SessionList = s.SessionList
})
.SelectMany(e => e.SessionList.Select(s => new
{
ID = e.ClassID,
Name = e.Name,
Session = s
}))

Query values in a Dictionary<ObjectId, Class> using LINQ?

Consider the following simple example of Students and Teachers;
// person
public class Person
{
public ObjectId Id { get; set; }
public string Name { get; set; }
public Person() {
Id = ObjectId.GenerateNewId(DateTime.Now);
}
}
// student has a Classroom
public class Student : Person
{
public string Classroom { get; set; }
}
// teacher has a Dictionary<ObjectId, Student> Students
public class Teacher : Person
{
[BsonDictionaryOptions(DictionaryRepresentation.ArrayOfDocuments)]
public Dictionary<ObjectId, Student> Students { get; set; }
public Teacher() {
Students = new Dictionary<ObjectId, Student>();
}
}
class Program
{
static void Main(string[] args)
{
var server = MongoServer.Create("mongodb://localhost/database?safe=true");
var database = server.GetDatabase("sandbox");
var collection = database.GetCollection<Teacher>("teachers");
collection.Drop();
// create students
var s1 = new Student() { Name = "s1", Classroom = "foo" };
var s2 = new Student() { Name = "s2", Classroom = "foo" };
var s3 = new Student() { Name = "s3", Classroom = "baz" };
var s4 = new Student() { Name = "s4", Classroom = "foo" };
// teacher 1
var t1 = new Teacher() { Name = "t1" };
t1.Students.Add(s1.Id, s1);
t1.Students.Add(s2.Id, s2);
collection.Insert(t1);
// teacher 2
var t2 = new Teacher {Name = "t2"};
t2.Students.Add(s3.Id, s3);
collection.Insert(t2);
// add teacher 3
var t3 = new Teacher() {Name = "t3"};
t3.Students.Add(s4.Id, s4);
collection.Insert(t3);
// select via key
var onlyt1 = collection.AsQueryable().Where(t => t.Students.ContainsKey(s1.Id)).ToList();
Console.WriteLine("onlyt1 : {0}", onlyt1.ToJson());
Console.ReadLine();
}
}
I can select via the key (shown above), but how do I find all the teachers who have students with classroom of "foo"? I want to write something like;
// select via value
var shouldBeJustT1andT3 = collection.AsQueryable().Where(t => t.Students.Values.Where(s => s.Classroom == "foo")).ToList();
You can use Any to get any teacher for whom there are students in a given classroom "foo":
List<Teacher> shouldBeJustT1andT3 = collection.Where(
teacher => teacher.Students.Any(student => student.Classroom == "foo")
).ToList();
Edit
Since Mongo's IQueryable isn't supporting Any by default, maybe you could just use Where and Count instead of Any:
List<Teacher> shouldBeJustT1andT3 = collection.Where(
teacher => teacher.Students.Where(student => student.Classroom == "foo").Count() > 0
).ToList();
Can't you have Students of type just ICollection<Person>?
Then you don't need query dictionary's values but flat objects' list, i.e. where s.ID == x && s.Classroom == "blah".
Dictionary makes sense to find object by key only, i.e. t.Students[studentId].
To find teachers: see dbaseman's answer, he's correct.

How to combine three lists of objects by primary key using linq

I'm trying to combine 3 lists of objects. I have a person list, address list and an addressRelation list.
I want to combine these lists into a new list ordered by person.id, use it as a datasource for a listview, and then be able to access the properties in the aspx page.
Is this possible?
Roughly
using System.Linq;
class Person
{
public int Id;
public string Name;
}
class Address
{
public int Id;
public string Street;
}
class PersonAddress
{
public int PersonId, AddressId;
}
public class Program
{
public static void Main(string[] args)
{
var personList = new []
{
new Person { Id = 1, Name = "Pete" },
new Person { Id = 2, Name = "Mary" },
new Person { Id = 3, Name = "Joe" }
};
var addressList = new []
{
new Address { Id = 100, Street = "Home Lane" },
new Address { Id = 101, Street = "Church Way" },
new Address { Id = 102, Street = "Sandy Blvd" }
};
var relations = new []
{
new PersonAddress { PersonId = 1, AddressId = 101 },
new PersonAddress { PersonId = 3, AddressId = 101 },
new PersonAddress { PersonId = 2, AddressId = 102 },
new PersonAddress { PersonId = 2, AddressId = 100 }
};
var joined =
from par in relations
join p in personList
on par.PersonId equals p.Id
join a in addressList
on par.AddressId equals a.Id
select new { Person = p, Address = a };
foreach (var record in joined)
System.Console.WriteLine("{0} lives on {1}",
record.Person.Name,
record.Address.Street);
}
}
Outputs:
Pete lives on Church Way
Mary lives on Sandy Blvd
Mary lives on Home Lane
Joe lives on Church Way

Categories

Resources