How to update my model code using LINQ - c#

here is my model code
public class Question
{
public int ID { set; get; }
public string QuestionText { set; get; }
public List<Answer> Answers { set; get; }
[Required]
public string SelectedAnswer { set; get; }
public Question()
{
Answers = new List<Answer>();
}
}
public class Answer
{
public int ID { set; get; }
public string AnswerText { set; get; }
public string IsSelected { set; get; }
}
public class Evaluation
{
public List<Question> Questions { set; get; }
public Evaluation()
{
Questions = new List<Question>();
}
}
this way i am updating my model
public void Edit(Evaluation model)
{
var evalVM = new Evaluation();
var q1 = new Question { ID = 1, QuestionText = "What is your favourite language" };
q1.Answers.Add(new Answer { ID = 12, AnswerText = "PHP", IsSelected = "" });
q1.Answers.Add(new Answer { ID = 13, AnswerText = "ASP.NET", IsSelected = "" });
q1.Answers.Add(new Answer { ID = 14, AnswerText = "Java", IsSelected = "" });
evalVM.Questions.Add(q1);
var q2 = new Question { ID = 2, QuestionText = "What is your favourite DB" };
q2.Answers.Add(new Answer { ID = 16, AnswerText = "SQL Server", IsSelected = "" });
q2.Answers.Add(new Answer { ID = 17, AnswerText = "MySQL", IsSelected = "" });
q2.Answers.Add(new Answer { ID = 18, AnswerText = "Oracle", IsSelected = "" });
evalVM.Questions.Add(q2);
foreach (var a in model.Questions)
{
var selectedVal = a.SelectedAnswer;
foreach (var x in evalVM.Questions)
{
var Answer = x.Answers;
foreach (var y in Answer)
{
if (y.ID.ToString() == selectedVal)
{
y.IsSelected = "checked";
}
}
}
}
}
just see this line here i am iterate in foreach loop and update my model in loop
foreach (var a in model.Questions)
{
var selectedVal = a.SelectedAnswer;
foreach (var x in evalVM.Questions)
{
var Answer = x.Answers;
foreach (var y in Answer)
{
if (y.ID.ToString() == selectedVal)
{
y.IsSelected = "checked";
}
}
}
}
I don't want to iterate in loop to update my model rather I want to do it by LINQ. Please guide me what I need to write.

foreach (var selectedVal in model
.Questions
.Select(q => q.SelectedAnswer))
foreach (var x in evalVM
.Questions
.SelectMany(q => q.Answers)
.Where(answer => answer.ID.ToString() == selectedVal))
x.IsSelected = "checked";
or
var selectedValues = model
.Questions
.Select(q => q.SelectedAnswer);
foreach (var x in evalVM
.Questions
.SelectMany(q => q.Answers)
.Where(answer => selectedValues.Contains(answer.ID.ToString())))
x.IsSelected = "checked";

Related

LINQ query to get all data about object which is collection of objects when each item of collection has own collection

Could anyone give me a hint on how to resolve the next task?
I have such a classes structure
public class Test
{
public string Title { get; set; }
public ICollection<Question> Questions { get; set; }
}
public class Question
{
public string Description { get; set; }
public ICollection<AnswerItem> AnswerItems { get; set; }
}
public class AnswerItem
{
public string Defenition { get; set; }
public bool IsCorrect { get; set; }
}
After fetching the [Test] entity from DB I've got IQueryable<Test>. And further, I wonder how to get all Question entities (as a list) with all info where each Question item would have all info about AnswerItem collection.
I have tried the next query, but it returns only a collection of all answers:
var questList = test.SelectMany(t => t.Questions.SelectMany(q => q.AnswerItems)).ToList();
And I need something like this:
Questions = new List<Question>
{
new Question
{
Name = "Question_1",
AnswerItems = new List<AnswerItem>
{
new AnswerItem { Name = "answer_1", IsCorrect = false },
new AnswerItem { Name = "answer_2", IsCorrect = false }
}
},
new Question
{
Name = "Question_2",
AnswerItems = new List<AnswerItem>
{
new AnswerItem { Name = "answer_1", IsCorrect = false },
new AnswerItem { Name = "answer_2", IsCorrect = false }
}
}
}
Your query should looks like the following one:
var query =
from t in ctx.Tests
from q in t.Questions
select new
{
Name = q.Description,
AnswerItems = q.AnswerItems.Select(a => new
{
Name = a.Defenition,
IsCorrect = a.IsCorrect
})
.ToList()
}
};
var result = query.ToList();

c# linq Groupby query ignoring Where on bool

I have an IEnumerable and am trying to first filter with .Where on a bool and then GroupBy like this
int someInt = orderEditorViewModel.EditOrderFitters.Where(f => f.Delete == false).GroupBy(f => f.OrderFitter.Person).Count();
EditOrderFitters is a List of
public class EditOrderFitter
{
[Display(Name = "Delete?")]
public bool Delete { get; set; }
public bool Added { get; set; } // this is hidden
public OrderFitter OrderFitter { get; set; }
}
But the query includes EditOrderFitter even when Delete is true
I used this longwinded workaround to filter out first
List<EditOrderFitter> notDeletedOrderFitters = new List<EditOrderFitter>();
foreach (EditOrderFitter e in orderEditorViewModel.EditOrderFitters)
{
if (!e.Delete)
{
notDeletedOrderFitters.Add(e);
}
}
And then:
int someInt = notDeletedOrderFitters.GroupBy(f => f.OrderFitter.Person).Count();
That works, but what's wrong with the
.Where(f => f.Delete == false)
in the first linq query. I also tried this:
int someInt = orderEditorViewModel.EditOrderFitters.Where(f => !f.Delete).GroupBy(f => f.OrderFitter.Person).Count();
but again the list wasn't filtered
Apologies everyone, I was looking at the LHS of this if statement to test for duplicate entries in a list when I should have been looking at both
if (orderEditorViewModel.EditOrderFitters.Where(f => f.Delete == false).GroupBy(f => f.OrderFitter.Person).Count() < orderEditorViewModel.EditOrderFitters.Where(f => f.Delete == false).Count())
Thanks for the replies and comments!
I forgot to put the delete on both sides
I've just reproduced your situation and it gives me the correct result, You can check to live here
using System;
using System.Linq;
// https://stackoverflow.com/questions/59702370/c-sharp-linq-groupby-query-ignoring-where-on-bool
public class Program
{
public static void Main()
{
var orderEditorViewModel = new
{
ParentName = "xyz",
EditOrderFitters = new []
{
new EditOrderFitter { Delete = true, OrderFitter = new OrderFitter { Id = 1, Person = "1" } },
new EditOrderFitter { Delete = false, OrderFitter = new OrderFitter { Id = 1, Person = "2" } },
new EditOrderFitter { Delete = false, OrderFitter = new OrderFitter { Id = 1, Person = "2" } },
new EditOrderFitter { Delete = false, OrderFitter = new OrderFitter { Id = 1, Person = "3" } }
}
};
var result = orderEditorViewModel.EditOrderFitters.Where(f => !f.Delete).GroupBy(f => f.OrderFitter.Person);
foreach(var item in result)
Console.WriteLine("" + " Count: " + item.Count());
}
public class EditOrderFitter
{
public bool Delete { get; set; }
public bool Added { get; set; }
public OrderFitter OrderFitter { get; set; }
}
public class OrderFitter
{
public int Id { get; set; }
public string Person { get; set; }
}
}

How to convert Model List to Json

I am trying to create an json data similar to this https://cdn.jsdelivr.net/gh/highcharts/highcharts#v7.0.0/samples/data/world-mortality.json
The current output I am getting is like this. The model name is being displayed and child does not seems to work. is t possible to remove the model field name on the serialize?
[{Name:"ABC",
Firstchild:[{Name:"AIR IMPORT",
Secondchild:[{NAME:"SCMBOA00052997",VALUE:69.7500},
{NAME:"SH123",VALUE:-100.0000},
{NAME:"SH456",VALUE:50.0000},
{NAME:"SH789",VALUE:150.0000}]
}]
}{Name:"DEF",
Firstchild:[{Name:"AIR IMPORT",
Secondchild:[{NAME:"SCMBOA00052997",VALUE:69.7500},
{NAME:"SH111",VALUE:-10.0000},
{NAME:"SH222",VALUE:80.0000},
{NAME:"SH333",VALUE:160.0000}]
}]
}]
What I need is like this
{
"ABC": {
"AIR IMPORT":{
"SH123": -100.0000,
"SH456": 50.0000,
"SH789": 150.0000
}
},
"DEF": {
"AIR IMPORT":{
"SH111": -10.0000,
"SH222": 80.0000,
"SH333": 160.0000
}
}
}
MODEL
public class ParentTreemap
{
public string Name { get; set; }
public List<FirstChildTreemap> Firstchild { get; set; }
}
public class FirstChildTreemap
{
public string Name { get; set; }
public List<SecondChildTreemap> Secondchild { get; set; }
}
public class SecondChildTreemap
{
[JsonProperty]
public string Name { get; set; }
[JsonProperty]
public decimal Value { get; set; }
}
Controller
var parent = treemaplist.Where(s => s.Parent == 0);
List<ParentTreemap> plist = new List<ParentTreemap>();
foreach (var item in parent)
{
var firstchild = treemaplist.Where(s => s.Parent == item.Id && s.Value==0);
List<FirstChildTreemap> flist = new List<FirstChildTreemap>();
foreach (var fitem in firstchild)
{
var secondchild = treemaplist.Where(s => s.Parent == fitem.Id && s.Value!=0);
List<SecondChildTreemap> slist = new List<SecondChildTreemap>();
foreach (var sitem in secondchild)
{
SecondChildTreemap model = new SecondChildTreemap();
model.Name = sitem.Name;
model.Value = sitem.Value;
slist.Add(model);
}
FirstChildTreemap child = new FirstChildTreemap();
child.Name = fitem.Name;
child.Secondchild = slist;
flist.Add(child);
}
ParentTreemap pmodel = new ParentTreemap();
pmodel.Name = item.Name;
pmodel.Firstchild = flist;
plist.Add(pmodel);
}
var stringWriter = new StringWriter();
var serializer = new JsonSerializer();
using (var writer = new JsonTextWriter(stringWriter))
{
writer.QuoteName = false;
serializer.Serialize(writer, plist);
}
ViewData["result"] = stringWriter;

How to use condition for all children in Entity Framework

I have these classes:
public class product
{
public int Id { get; set; }
public string Title { get; set; }
public Store Store { get; set; }
public ICollection<Color> Colors { get; set; }
}
public class Color
{
public int Id { get; set; }
public string Name { get; set; }
public product Product { get; set; }
}
public class Store
{
public int Id { get; set; }
public string Name { get; set; }
public string City { get; set; }
public ICollection<product> Products { get; set; }
}
And I have this list :
List<Store> Stores = new List<Store>
{
new Store { Id = 1, Name = "Lilo", City = "Teh",
Products = new List<product>
{
new product
{ Id = 1, Title = "Asus",
Colors = new List<Color> {
new Color { Id = 1, Name = "Blue"},
new Color { Id = 2, Name = "Orange"}
}
},
new product
{ Id = 2, Title = "Dell",
Colors = new List<Color> {
new Color { Id = 1, Name = "Yellow"},
new Color { Id = 2, Name = "Orange"},
new Color { Id = 3, Name = "Red"}
}
}
}
},
new Store{Id=2,Name="filo",City="san",
Products=new List<product>
{
new product{Id=3,Title="Asus",
Colors=new List<Color>{
new Color{Id=1,Name="Blue"},
new Color{Id=2,Name="Orange"}
}
},
new product{Id=4,Title="Dell",
Colors=new List<Color>{
new Color{Id=1,Name="Yellow"},
new Color{Id=2,Name="Lime"},
new Color{Id=3,Name="Red"}
}
}
}
}
};
I want to select all stores where Name ="Lilo" and products names is "Dell " and Color="Blue". I want do this in Entity Framework, not Linq.
I use this code but it doesn't work :
var test = Stores.Where(s => s.Name = "lilo" && s.Products.Where(p => p.Title == "Dell").FirstOrDefault().Title == "Dell" && s.Products.Where(c => c.Colors.Where(ct => ct.Name == "Blue").FirstOrDefault().Name = "Blue")).ToList();
How can I do this ?
Do this By Method Syntax :
var stlist = Stores.Where(s => s.Name.ToLower() == "lilo" && s.Products.Where(p => p.Colors.Any(c=>c.Name=="Blue") && p.Title == "Dell").FirstOrDefault().Title == "Dell").ToList();
Updated :
And Hopeless's Answers is (best answers):
var lslist2= Stores.Where(s => s.Name == "lilo" && s.Products.Any(p => p.Title == "Dell" && p.Colors.Any(c => c.Color.Name == "Blue"))).ToList();
And by Linq :
var test = (from s in Stores
from p in s.Products
from c in p.Colors
where s.Name=="Lilo" && p.Title=="Dell"&& c.Name=="Blue"
select s
).ToList();

How to transform 2-levels-deep foreach loop to LINQ expression to produce Dictionary<string,SomeList<Item>>?

How do I transform this function:
void MyFunc () {
foreach (var k in problems.Keys)
{
var list = new ObservableCollection<ListViewItem>();
listViewItems.Add(k, list);
foreach (var i in problems[k].Items)
{
list.Add(new ListViewItem
{
Token = i.Token,
IsFatalError = i.IsFatal,
Checked = false,
Line = i.Token.Position.Line,
Description = i.Description,
BackgroundBrush = i.IsFatal ? Brushes.Red : null
});
}
}
}
to LINQ query syntax ? here are the types and variables:
public class ProblemsList {
public class Problem {
public IToken Token { get; set; }
public string Description { get; set; }
public bool IsFatal { get; set; }
}
public List<Problem> Items { get { return problems; } }
}
public class ListViewItem {
public bool IsFatalError { get; set; }
public bool Checked { get; set; }
public int Line { get; set; }
public string Description { get; set; }
public Brush BackgroundBrush { get; set; }
}
Dictionary<string, ProblemsList> problems;
Dictionary<string, ObservableCollection<ListViewItem>> listViewItems
= new Dictionary<string, ObservableCollection<ListViewItem>>();
Here's how I would do it (using chained methods syntax):
listViewItems = problems.ToDictionary(
p => p.Key,
p => new ObservableCollection<ListViewItem>(
p.Value.Items.Select(
i => new ListViewItem
{
Token = i.Token,
IsFatalError = i.IsFatal,
Checked = false,
Line = i.Token.Position.Line,
Description = i.Description,
BackgroundBrush = i.IsFatal ? Brushes.Red : null
}
)
)
);
Update
A version that uses query syntax as much as possible:
listViewItems = (
from p in problems
select new
{
Key = p.Key,
Value = from i in p.Value.Items
select new ListViewItem
{
Token = i.Token,
IsFatalError = i.IsFatal,
Checked = false,
Line = i.Token.Position.Line,
Description = i.Description,
BackgroundBrush = i.IsFatal
? Brushes.Red
: null
}
}
).ToDictionary(x => x.Key, x => x.Value);

Categories