I'm new to ASP.NET MVC , I wrote C# code for search in table that search for the person name how can I store the full row to use the other information for the same person such as age, gender?
public ActionResult Index(string searching)
{
var PersonTable = db.Person;
var Name= PersonTable.Where(x => x.Name.ToLower().Contains(searching.ToLower()));
return null;
}
i try to explain with example, in my case i get the whole row by 'select s'
public void LinqTest() {
List<Student> list1 = new List<Student> {
new Student() {id=1,name="Ali Imran",age=25 },
new Student() {id=1,name="Usman Ali",age=27 },
new Student() {id=1,name="Umer Ali",age=30 },
};
var result = from s in list1 where s.age>27 select s ;
foreach (Student std in result)
{
Console.WriteLine(std.id+"-"+std.name + "-" + std.age);
}
}
Related
public class Person
{
public string firstName;
public string lastName;
}
I want a list of all Persons with a unique first name.
Persons table
Tom Haverford
Tom Baker
Amy Pond
Amy Santiago
Trish Walker
Chidi Anagonye
The query should return
Trish, Chidi
I've tried using Distinct and a combination of GroupBy and Select, but those return Trish, Chidi, Tom, Amy.
Demo on dotnet fiddle
You can Group by then count number of duplicated items. After that, you can get the item with count value equals to 1 like below.
var arr = new []
{
new Person { firstName = "Tom", lastName = "Haverford" },
new Person { firstName = "Tom", lastName = "Baker"},
new Person { firstName = "Amy", lastName = "Pond" },
new Person { firstName = "Amy", lastName = "Santiago"},
new Person { firstName = "Trish", lastName = "Walker"},
new Person { firstName = "Chidi", lastName ="Anagonye" }
};
var result = arr.GroupBy(p => p.firstName).Select(g => new { Name = g.Key, Count = g.Count()});
foreach(var item in result.Where(p => p.Count == 1))
Console.WriteLine(item.Name);
Output
Trish
Chidi
You can use group by and count functionality together for this :
1. Get a list of all persons from DB :
var personList = (from p in db.Person select p).ToList(); // I assumed here that your db obj name is 'db' and table name is 'Person'
2. Now apply group by query to get the count of first names :
var q = from x in personList
group x by x.firstName into g
let count = g.Count()
select new {Count = count, Name = g.First().firstName };
3. Now you can get your final result like this :
var finalResult = (from p in q where p.Count == 1 select p).ToList();
Happy Coding...
I have a list with items as follows:
public class Student {
public string Name;
public string Nickname;
}
var students = new List<Student> { new Student {Name = "Becca", Nickname = "Rebecca"},
new Student {Name = "Ray", Nickname = "Raymond"}}
If I want to swap Name and Nickname so that students would now be
var students = new List<Student> { new Student {Name = "Rebecca", Nickname = "Becca"},
new Student {Name = "Raymond", Nickname = "Ray"}}
How do I do that in linq?
You can use Linq's Select method to create a new instance of student with the values swapped.
var students = new List<Student>
{
new Student {Name = "Becca", Nickname = "Rebecca"},
new Student {Name = "Ray", Nickname = "Raymond"}
}
var swapped = students.Select(x => new Student {Name = x.Nickname, Nickname = x.Name});
Whenever we ask how to do X with each item in a list, the answer is usually two things: How to do X, and how to do something with each item in a list. Once we see that, we can separate the two problems and start with how to do X. The second part, how to do anything with each item in a list, is much simpler.
In this case, how do we do X - create a new Student from an existing one, with the names swapped?
That could be a method like this:
Student SwapNames(Student student)
{
return new Student {Name = student.Nickname, Nickname = student.Name};
}
or simplified as
Student SwapNames(Student student) =>
new Student {Name = student.Nickname, Nickname = student.Name};
Having solved that, determining how to do it to to items in a list is easier.
var swappedStudents = new List<Student>();
foreach(var student in originalStudents)
{
swappedStudents.Add(SwapNames(student));
}
Or, using LINQ:
var swappedStudents = originalStudents.Select(student => SwapNames(student));
...or simplified:
var swappedStudents = originalStudents.Select(SwapNames);
These both produce an IEnumerable<Student>. If we wanted a List<Student> we could append:
var swappedStudents = originalStudents.Select(SwapNames).ToList();
In the examples so far, the method that does X - in this case, swapping the names, is in a separate function. That can be helpful for readability. But we can also do it inline with an anonymous function, like this:
var swappedStudents = originalStudents.Select(
student => new Student { Name = student.Nickname, Nickname = student.Name });
That's an anonymous function that takes a Student as an argument and returns a new Student with the names swapped.
Hello I'm making a controller through its URL you can obtain certain items from a list. If you input a letter all students in the hard coded list whos surname start with letter are shown on the webpage. But I'm struggling with the LINQ query because when using the code below I'm getting a blank page no matter what. What am I doing wrong and how can I obtain the elements I need and have them in a list?
EDIT: Lower case in URL was the issue. Thank you!
public IActionResult Surname(string letter)
{
string query = letter;
// if(letter != null) { query = letter; }
List<Student> studenten = new List<Student>()
{
new Student { Naam = "Johan", Achternaam = "Jacobs" },
new Student { Naam = "Karel", Achternaam = "Jay" },
new Student { Naam = "John", Achternaam = "Jas" }
};
List<Student> newStudents = studenten.Where(x => x.Achternaam.StartsWith(query) == true)
.ToList();
ViewData["Student"] = newStudents;
return View();
}
You should make use of an overload of StartsWith method:
public bool StartsWith(
string value,
bool ignoreCase, // set this as true
CultureInfo culture // set this as invariant culture
)
var newStudents = studenten.Where(x => x.Achternaam
.StartsWith(
query,
true,
CultureInfo.InvariantCulture))
.ToList();
Doing so if your url is the following one:
Controller/Index/?letter=j
or this one:
Controller/Index/?letter=J
you would get always the results your are looking for.
For me, your code works like a charm. However, you have to input uppercase J letter, as you do not check for case sensitivity.
To achieve desired results Where clause should look like:
newStudents = studenten.Where(x => x.Achternaam.ToLower().StartsWith(query.ToLower()))
Moreover, you could move ToLower to query assigning line, to make it a bit more readable like:
public IActionResult Surname(string letter)
{
string query = letter.ToLower();
List<Student> studenten = new List<Student>()
{
new Student { Naam = "Johan", Achternaam = "Jacobs" },
new Student { Naam = "Karel", Achternaam = "Jay" },
new Student { Naam = "John", Achternaam = "Jas" }
};
List<Student> newStudents = studenten.Where(x => x.Achternaam.ToLower().StartsWith(query)).ToList();
ViewData["Student"] = newStudents;
return View();
}
Also, == true part is redundant, as StartsWith returns boolean value (which you are comparing to, by the way).
I think it's missing the ToLower function, because your url is like this Controller/Index/?letter=j. Try this:
public IActionResult Surname(string letter)
{
string query = letter;
// if(letter != null) { query = letter; }
List<Student> studenten = new List<Student>()
{
new Student { Naam = "Johan", Achternaam = "Jacobs" },
new Student { Naam = "Karel", Achternaam = "Jay" },
new Student { Naam = "John", Achternaam = "Jas" }
};
List<Student> newStudents = studenten.Where(x => x.Achternaam.ToLower().StartsWith(query.ToLower()) == true).ToList();
ViewData["Student"] = newStudents;
return View();
}
I have a list of Objects and one of the item is another list. How can I Group them based on the inner list.
Here is an example of what I wish to do.
class Student
{
public string Name;
public int Age;
public List<GroupInfo> GroupList; // This is the inner list
}
class GroupInfo
{
public string GroupName;
public int GroupId;
}
static void Main()
{
GroupInfo firstGroup = new GroupInfo
{
GroupId = 1,
GroupName = "First group"
};
GroupInfo secondGroup = new GroupInfo
{
GroupId = 2,
GroupName = "Second group"
};
GroupInfo thirdGroup = new GroupInfo
{
GroupId = 3,
GroupName = "Third group"
};
GroupInfo fourthGroup = new GroupInfo
{
GroupId = 4,
GroupName = "Fourth group"
};
List<Student> studentList = new List<Student>();
Student firstStudent = new Student();
firstStudent.Name = "Name1";
firstStudent.Age = 15;
firstStudent.GroupList = new List<GroupInfo>();
firstStudent.GroupList.Add(firstGroup);
firstStudent.GroupList.Add(secondGroup);
studentList.Add(firstStudent);
Student secondStudent = new Student();
secondStudent.Name = "Name2";
secondStudent.Age = 17;
secondStudent.GroupList = new List<GroupInfo>();
secondStudent.GroupList.Add(firstGroup);
secondStudent.GroupList.Add(thirdGroup);
studentList.Add(secondStudent);
Student thirdStudent = new Student();
thirdStudent.Name = "Name3";
thirdStudent.Age = 18;
thirdStudent.GroupList = new List<GroupInfo>();
thirdStudent.GroupList.Add(secondGroup);
thirdStudent.GroupList.Add(thirdGroup);
thirdStudent.GroupList.Add(fourthGroup);
studentList.Add(thirdStudent);
List<GroupInfo> groupInfoList = new List<GroupInfo>();
// Now What I want is to get a group List Where...
foreach (var student in studentList)
{
// ...First Group Should contains firstStudent and secondStudent
// Second group Should firstStudent & thirdStudent
// Third group Should contains secondStudent & thirdStuden
// Fourth Group Should contains only thirdStudent
}
}
One way is to iterate on the whole List and populate the GroupInfo List. Just wondering is there any other way to do this task.
You can do this with SelectMany like this:-
var result = studentList.SelectMany(x => x.GroupList,
(studentObj, groups) => new { studentObj, groups })
.GroupBy(x => new { x.groups.GroupId, x.groups.GroupName })
.Select(x => new
{
GroupId = x.Key.GroupId,
GroupName = x.Key.GroupName,
Students = x.Select(z => z.studentObj).ToList()
});
Since your GroupInfo class only has two properties i.e. GroupId & GroupName, you won't be able to fetch the Students associated with it. This is the reason I am fetching anonymous type out of it.
I am getting following output with this query:-
I have the following responses from the API. How can I group them into the following structure?
Student[]
- Name
- Classes[]
- ClassName
- ClassId
- ClassCategories[]
- CategoryName
- CategoryWeight
- Assignments[]
- AssignmentName
- Score
I was managed to group them until the "Classes" level but unable to get the ClassCategories for each of the classes
var data = (from result in results
group result by new { result.StudentId, result.FirstName, result.LastName, result.MiddleInitial }
into StudentGroup
select new GroupedStudent
{
StudentId = StudentGroup.Key.StudentId,
FullName = string.Format("{0} {1} {2}", StudentGroup.Key.FirstName, StudentGroup.Key.MiddleInitial, StudentGroup.Key.LastName).Replace(" ", " "),
Classes = from result in results
group result by new { result.ClassId, result.ClassName } into ClassGroup
select new groupedClass
{
ClassName = ClassGroup.Key.ClassName,
ClassId = ClassGroup.Key.ClassId,
ClassCategories = ...
})
}).ToList();
Can anyone please assists me? Thank you.
First, you have make ClassGroup from StudentGroup not from results.
Classes = from s in StudentGroup group result by new { s.ClassId, s.ClassName } into ClassGroup
The complete linq query is as follows:
var data =
(from result in results
group result by new { result.StudentId, result.FirstName, result.LastName, result.MiddleInitial } into StudentGroup
select new
{
StudentId = StudentGroup.Key.StudentId,
FullName = string.Format("{0} {1} {2}", StudentGroup.Key.FirstName, StudentGroup.Key.MiddleInitial, StudentGroup.Key.LastName).Replace(" ", " "),
Classes = (from s in StudentGroup
group s by new { s.ClassId, s.ClassName } into ClassGroup
select new
{
ClassId = ClassGroup.Key.ClassId,
ClassName = ClassGroup.Key.ClassName,
ClassCategories = (from c in ClassGroup
group c by new { c.CategoryName, c.CategoryWeight } into CategoryGroup
select new
{
CategoryName = CategoryGroup.Key.CategoryName,
CategoryWeight = CategoryGroup.Key.CategoryWeight,
Assignments = (from ct in CategoryGroup
group ct by new { ct.AssignmentName, ct.Score } into AssingnmentGroup
select new
{
AssignmentName = AssingnmentGroup.Key.AssignmentName,
Score = AssingnmentGroup.Key.Score
}).ToList()
}).ToList()
}).ToList()
}).ToList();
For example, if you want to access to the first Assignment's score, you can get it like this:
var student = data.FirstOrDefault();
var score = student.Classes[0].ClassCategories[0].Assignments[0].Score;
This is usually how I do It.
Create a class to store your data
Create a list of that class type
In your case instead of string dataRow maybe you can use a sub class
.
// get data from webservice
var json = webClient.DownloadString(url);
var values = JsonConvert.DeserializeObject<JArray>(json);
// create a list to save all the element
List<myClass> classList = new List<myClass>();
// process every row
foreach (string dataRow in values)
{
string[] dataField = dataRow.Split(',');
// have a constructor to assign each value to this element
myClass ctROW = new myClass(dataField);
classList.add(ctROW );