How to return lIEnumerable list - c#

i am new to programming and i got stuck. I am not very sure how to return my list. Can someone help now i get only System.IEnumerable and if i try to use foreach i cant iterate over the Employee
public class Employee
{
public string Name { get; set; }
public int Id { get; set; }
public IEnumerable<Employee> GetEmployees()
{
return new List<Employee>
{
new Employee { Name = "Tom", Id = 1 },
new Employee { Name = "Peter", Id = 3 },
new Employee { Name = "Michael", Id = 2 }
};
}
}
class Program
{
static void Main(string[] args)
{
var employee = new Employee();
foreach(var emp in Employee)
{
}
}
}

You can do like this.
Employee emp = new Employee();
IEnumerable<Employee> ls = emp.GetEmployees();
foreach( Employee e in ls)
{
}

In your foreach loop, you forgot to invoke your method GetEmployees. You need to do it if you want to iterate over it.
foreach(var emp in Employee.GetEmployees())

Related

How to convert List<string> to List<object> specific property in C#

How to convert List<string> to List<object> property in c#
We have a list of email id's
List<string> str= new List<string>{"abc1#gmail.com","abc2#gmail.com"};
and now we have to assign these email IDs to the list of an employee List<Employee> emailId property.
var emplist = new List<Employee>() ;
You can use Select().
var emplist = str.Select(x => new Employee { EmailId = x }).ToList();
Select() is used for projecting each element of a sequence(in your case it is string email id) into a new sequence i.e. the Employee object.
We can convert or assign List<string> to List<object> to specific property
//here Employee is an Object type
public static void Main(string[] args)
{
List<string> list = new List<string>() { "abc1#gmail.com", "abc2#gmail.com" } ;
var emplist= new List<Employee>() ;
if(list.Any())
list.ForEach(str => emplist.Add(new Employee { EmailId = str }));
Console.ReadLine();
}
public class Employee {
public string EmailId { get; set; }
public string Address { get; set; }
}

How to display a list of a model in a C# console application

I am new to C# and I have been struggling to do the following:
I'm trying to List a list in a console application, I have a model called "TeamModel"
public class TeamModel
{
public int Id { get; set; }
public string TeamName { get; set; }
public List<PersonModel> TeamMembers { get; set; } = new List<PersonModel>();
public TeamModel()
{
}
}
In my main class I have the following:
class Program
{
static void Main(string[] args)
{
List<TeamModel> TeamOne = new List<TeamModel>(){new TeamModel() { Id =1, TeamName = "x's Team", TeamMembers = null}};
List<TeamModel> TeamTwo = new List<TeamModel>(){new TeamModel() { Id =2, TeamName = "y's Team", TeamMembers = null}};
List<TeamModel> TeamThree = new List<TeamModel>(){new TeamModel() { Id =3, TeamName = "z's Team", TeamMembers = null}};
List<List<TeamModel>> listOfTeams = new List<List<TeamModel>> (){TeamOne,TeamTwo,TeamThree};
foreach (List<TeamModel> list in listOfTeams)
{
Console.WriteLine(list);
}
}
}
Now when I run the program I expect the result to be:
1,x's Team ,
2,y's Team ,
3,z's Team
Instead what I'm getting is
System.Collections.Generic.List`1[TeamModel]
System.Collections.Generic.List`1[TeamModel]
System.Collections.Generic.List`1[TeamModel]
If I change the foreach to :
foreach (List<TeamModel> list in listOfTeams)
{
Console.WriteLine(String.Join(", ", list));
}
I get this:
TeamModel
TeamModel
TeamModel
You can achieve this by using
foreach (List<TeamModel> list in listOfTeams)
{
foreach (var team in list)
{
Console.WriteLine(team.Id + " " + team.Name);
}
}
Is there a reason that TeamOne, TeamTwo and TeamThree are created as lists given that each "list" contains a single team? The following implementation would achieve what you stated was the expected output:
static void Main(string[] args)
{
TeamModel TeamOne = new TeamModel { Id = 1, TeamName = "x's Team", TeamMembers = null };
TeamModel TeamTwo = new TeamModel { Id = 2, TeamName = "y's Team", TeamMembers = null };
TeamModel TeamThree = new TeamModel { Id = 3, TeamName = "z's Team", TeamMembers = null };
List<TeamModel> listOfTeams = new List<TeamModel> { TeamOne, TeamTwo, TeamThree };
foreach (TeamModel team in listOfTeams)
{
Console.WriteLine($"{team.Id}. {team.TeamName}");
}
}
If you genuinely need a list of lists then the following implementation will work. The only difference from your own solution is an additional foreach inside the one you had:
static void Main(string[] args)
{
List<TeamModel> TeamOne = new List<TeamModel>() { new TeamModel() { Id = 1, TeamName = "x's Team", TeamMembers = null } };
List<TeamModel> TeamTwo = new List<TeamModel>() { new TeamModel() { Id = 2, TeamName = "y's Team", TeamMembers = null } };
List<TeamModel> TeamThree = new List<TeamModel>() { new TeamModel() { Id = 3, TeamName = "z's Team", TeamMembers = null } };
List<List<TeamModel>> listOfTeams = new List<List<TeamModel>>() { TeamOne, TeamTwo, TeamThree };
foreach (List<TeamModel> list in listOfTeams)
{
foreach (TeamModel team in list)
{
Console.WriteLine($"{team.Id}. {team.TeamName}");
}
}
}
Using Linq
You can Flatten the nested list using .SelectMany() and then either you can iterate over flatten list or you can convert it into List of string and then print it.
Projects each element of a sequence to an IEnumerable and flattens
the resulting sequences into one sequence.
var strTeamDetails = listOfTeams
.SelectMany(teams => teams) //Flatten the List.
.Select(individualTeam => $"{individualTeam.Id} {individualTeam.Name}"); //Convert to IEnumearable of string
Console.WriteLine(string.Join(",\n", strTeamDetails)); //Print
You may want to consider overriding the ToString() method for your TeamModel class;
From the link above;
class Person
{
public string Name { get; set; }
public int Age { get; set; }
public override string ToString()
{
return "Person: " + Name + " " + Age;
}
}
You can test the ToString method as shown in the following code example:
Person person = new Person { Name = "John", Age = 12 };
Console.WriteLine(person);
// Output:
// Person: John 12

From a one to many situation how do I get common items in Entity Framework

I just started with Entity Framework and I was having difficulty generating a query for the following situation.
I currently have two model classes Student and Sport. A student can play multiple sports. This is what my models look like
public class DbContext : DbContext
{
public DbContext(): base("name=DbContext")
{
}
public DbSet<Student> MyStudents { get; set; }
public DbSet<Sport> MySports { get; set; }
}
public class Student
{
public List<Sport> Actions { get; set; }
public string Name { get; set; }
}
public class Sport
{
public string SportName { get; set; }
}
My question is how do I get a list of all sports played by all the students? In short I am looking for common sports. So basically in the following case
Student A played Sports : Soccer , Tennis , Bowling
Student B played Sports : Soccer , Tennis ,
Student C played Sport : Tennis
Then only Tennis should be returned
Using the DB schema you've provided you can get the common sports checking sports of each student:
var sports = new[]
{
new Sport { SportName = "Tennis" },
new Sport { SportName = "Soccer" },
new Sport { SportName = "Bowling" }
};
var students = new[]
{
new Student
{
Name = "Student 1",
Actions = sports
},
new Student
{
Name = "Student 2",
Actions = new[] { sports[0], sports[1] }
},
new Student
{
Name = "Student 3",
Actions = new[] { sports[0] }
}
};
// Or
var sports = context.Sports;
var students = context.Students;
// In case students' sports are objects (as in this sample) you can use such a query:
var commonSports = sports.Where(sport =>
students.All(student => student.Actions.Contains(sport)));
// In case you're going to check the sports by name, this:
var commonSports = sports.Where(sport =>
students.All(student => student.Actions.Any(studSport =>
studSport.SportName == sport.SportName)));
Console.WriteLine($"Comon sports: {string.Join(",", commonSports.Select(i => i.SportName))}");
// To get only names of common sports:
var sportNames = commonSports.Select(i => i.SportName);
Console.Read();
If you use a relational database it would be easier and (as for me) more logical to implement many-to-many relationship as described here:
var context = new DbContext()
var unique = context.MyStudents.SelectMany(student => student.Actions.Select(sport => sport.SportName)).Distinct();
you just do this :
var commonSports = Context.Students.SelectMany(x=>x.Actions).GroupBy(x => x.SportName).Where(x=>x.Count()==items.Count(c=>c.Actions!=null)).Select(x=>x.Key).ToList();
I hope it been helpful .
To achieve this you might want to first set up some kind of model class, this isn't strictly necessary but might make things clearer for you:
public class StudentWithSports()
{
public string Name {get;set;}
public List<string> Sports {get;set;}
}
You can then populate your model from your context:
using(var context = new DbContext())
{
List<StudentWithSports> list = context
.Students
.Include(stu => stu.Actions)
.Select(stu => new StudenWithSports
{
Name = stu.Name,
Sports = stu.Actions.Select(act => act.SportName).ToList()
}).ToList();
}
If you don't want to create a model you could just do:
var list = context
.Students
.Include(stu => stu.Actions)
.Select(stu => new {
Name = stu.Name,
Sports = stu.Actions.Select(act => act.SportName).ToList()
}).ToList();
Which will give you a list of anonymous objects with the same properties.
The essence of my answer is the linq query, but I created a couple of classes to model your EF classes to show it works.
Student student1 = new Student
{
Name = "John",
Actions = new List<Sport>
{
new Sport { SportName = "Tennis" },
new Sport { SportName = "Soccer" },
new Sport { SportName = "Bowling" }
}
};
Student student2 = new Student
{
Name = "Mary",
Actions = new List<Sport>
{
new Sport { SportName = "Tennis" },
new Sport { SportName = "Soccer" }
}
};
Student student3 = new Student
{
Name = "Jane",
Actions = new List<Sport>
{
new Sport { SportName = "Tennis" }
}
};
IEnumerable<Student> students = new List<Student>
{
student1,
student2,
student3
};
var query = from s in students
select new
{
s.Name,
Sports = from sp in s.Actions
select sp.SportName
};
var result = query.ToList();
for (int i = 0; i < result.Count(); i++)
{
Console.Write(result[i].Name + " played sports: ");
foreach (var sport in result[i].Sports)
Console.Write(" " + sport);
Console.WriteLine();
}
Well your Db design isn't right because you have many to many relation between MyStudents and MySports tables. You have to add joint table between Students and Sports. You can call it StudentsSports
public class DbContext : DbContext
{
public DbContext(): base("name=DbContext")
{
}
public DbSet<Student> MyStudents { get; set; }
public DbSet<StudentsSport> StudentsSports { get; set; }
public DbSet<Sport> MySports { get; set; }
}
public class Student
{
public int ID { get; set; }
public List<StudentsSport> Actions { get; set; }
public string Name { get; set; }
}
public class Sport
{
public int ID { get; set; }
public string SportName { get; set; }
}
public class StudentsSport
{
public int ID { get; set; }
[ForeignKey(Student)]
public int StudentID { get; set; }
[ForeignKey(Sport)]
public int SportID { get; set; }
}
Then you can just do
var listOfActions = MyStudents.Select(s => s.Actions.Select(a => a.SportID));
var intersection = listOfActions
.Skip(1)
.Aggregate(
new HashSet<T>(listOfActions.First()),
(h, e) => { h.IntersectWith(e); return h; }
);
EDIT:
If you have students without sports then you will always get empty intersection list. If you don't want that then you will have to filter them
var listOfActions = MyStudents.Select(s => s.Actions.Select(a => a.SportID)).Where(c => c.Any());

LINQ select items in a list that are all in a list of another type

I have a many to many relation created using Entity Framework.
public class Animal
{
[Key]
[DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
public int AnimalID { get; set; }
[MaxLength(50)]
public string AnimalName { get; set; }
public virtual ICollection<Food> FoodList { get; set; }
}
public class Den
{
[Key]
[DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
public int DenID { get; set; }
[MaxLength(50)]
public string DenName { get; set; }
public virtual ICollection<Food> FoodList { get; set; }
}
Both Animal and Den contain virtual lists of type food.
public class Food
{
[Key]
[DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
public int FoodID { get; set; }
[MaxLength(50)]
public string FoodName { get; set; }
public virtual ICollection<Animal> AnimalList { get; set; }
public virtual ICollection<Den> DenList { get; set; }
}
I have a method which passes in a DenID and I need to return a list of animals that have ALL the foods in their Animal.FoodList that the Den has in it's Den.FoodList.
example if the Den.FoodList contains Meat and Veg then I want a list of Animals that have Meat and Veg in their foodList.
Edit
I have attempted a few things so far.
First of all I have this in my ViewModel
denFoodList = new List<Food>();
//Check if myDen requires any Food.
denFoodList = MyDen.FoodList.ToList();
I tried looping through each member of the DenFoodList and adding Animals to an Animal list and then gathering that any animal in the list x number of times (where x is the FoodList.Count() ) was the animals I needed, however this method was slow and messy.
I tried using the All method with the animals list and the DenList but I couldn't get it to work.
animalList = context.Animals.Where(a => a.FoodList.All(f => f.DenList));
I've been looking into using Joins and intersects but I have not been successful in using them to solve this problem yet.
End of Edit
Any help is appreciated.
Thanks.
Let's try this
class MyContext : DbContext {}
// ...
using (MyContext context = new MyContext())
{
var den = context.Den.Find(DenId);
// Inner join Linq
var foodList = from a in context.Animals
from b in a.FoodList
join c in d.FoodList on c.FoodId equals b.FoodId
select c;
}
Untested:
class Test
{
private static IEnumerable<Den> Dens()
{
var dens = new List<Den>
{
new Den
{
DenID = 1,
DenName = "GamePark",
FoodList = new Collection<Food>()
{
new Food
{
FoodID = 1,
FoodName = "Veg",
AnimalList = new Collection<Animal>
{
new Animal
{
AnimalID = 234,
AnimalName = "Zebra",
FoodList = new Collection<Food>{new Food {FoodID = 1, FoodName = "Veg"} }
},
new Animal
{
AnimalID = 125,
AnimalName = "Buffalo",
FoodList = new Collection<Food>{new Food {FoodID = 1, FoodName = "Veg"} }
}
}
},
new Food
{
FoodID = 2,
FoodName = "Meat",
AnimalList = new Collection<Animal>
{
new Animal
{
AnimalID = 003,
AnimalName = "Leopard",
FoodList = new Collection<Food>{new Food {FoodID = 2, FoodName = "Meat"} }
},
new Animal
{
AnimalID = 001,
AnimalName = "Lion",
FoodList = new Collection<Food>{new Food {FoodID = 2, FoodName = "Meat"} }
}
}
}
}
}
};
return dens;
}
public static IEnumerable<Animal> GetAnimalsWithFoodsInDen(int denId)
{
var den = Dens().FirstOrDefault(x => x.DenID == denId);
var animals = new List<Animal>();
if (den != null)
{
var foods = den.FoodList;
if (foods != null)
{
animals = foods.ToList().Aggregate(animals, (current, food) => current.Union(food.AnimalList).ToList());
}
}
return animals;
}
static void Main(string[] args)
{
var result = GetAnimalsWithFoodsInDen(1);
foreach (var a in result)
{
Console.WriteLine(a.AnimalName);
}
Console.ReadLine();
}
}
First get the list of food, then get the animals:
Den d = SomeDen();
var food = d.FoodList;
var animals = new List<Animal>();
foreach(var f in food) foreach(var a in f.AnimalList) if(!animals.Contains(a)) animals.Add(a);
Maybe you'd like a dictionary instead of List for performance, depending on your data.
Or perhaps you're looking for something like this?
Dan d = SomeDen();
var food = d.FoodList;
var animals = from a in DB.Animals
where a.FoodList.Any((f)=>food.Contains(f))
select a;
The latter should be your intuitive idea, but it's going to be quite slow.

Inheritance and Linq-to-Entities

I have the following models:
public class Person
{
long Id;
string name;
}
public class Student : Person
{
string studentId;
}
public class Bus
{
long Id;
public ICollection<Person> riders {set; get;}
}
public class SchoolBus : Bus
{
long schoolBusNumber;
}
I also have the following code:
SchoolBus schoolBus = new SchoolBus();
schoolBus.riders = new List<Person>
{
new Student { name = "Jim" },
new Student { name = "Jane }
}
var query = from rider in SchoolBus.riders
select new
{
(rider as Student).studentId;
}
Students and Person are set up as separate tables and I'm using DbContext.
I know why this would not work, but what are possible solutions for me to get this to return the right studentId by using a Person collection?
try this:
var studentIds = rider.OfType<Student>().Select(x => x.studentId);
If your code is exactly what you shown, this will work:
SchoolBus schoolBus = new SchoolBus();
schoolBus.riders = new List<Person>
{
new Student { name = "Jim" },
new Student { name = "Jane }
}
var query = from rider in SchoolBus.riders
select new
{
riderID = (rider as Student).studentId;
}
But if your query runs on linq2entity, you should show your exact code, and your problem.

Categories