StringBuilder within IEnumerable - c#

I have a ControlMeasure table that holds information on each control measure and a ControlMeasurepeopleExposed Table that holds a record for each person exposed in the control measure this could be 1 record or many records.
I Have a controller that populates a List view
For each item in the list, Control Measure, I would like to create a string that shows all the People at risk
e.g.
PeopleString = "Employees, Public, Others";
Ive added a foreach in the controller to show what I'm trying to do however I'm aware that this wont work.
The controller is this:
public ActionResult ControlMeasureList(int raId)
{
//Populate the list
var hazards = new List<Hazard>(db.Hazards);
var controlMeasures = new List<ControlMeasure>(db.ControlMeasures).Where(x => x.RiskAssessmentId == raId);
var cmcombined = (
from g in hazards
join f in controlMeasures
on new { g.HazardId } equals new { f.HazardId }
select new CMCombined
{
Activity = f.Activity,
ControlMeasureId = f.ControlMeasureId,
ExistingMeasure = f.ExistingMeasure,
HazardName = g.Name,
LikelihoodId = f.LikelihoodId,
Rating = f.Rating,
RiskAssessmentId = f.RiskAssessmentId,
SeverityId = f.SeverityId,
}).OrderBy(x => x.Activity).ToList();
var cmPeopleExp = new List<ControlMeasurePeopleExposed>(db.ControlMeasurePeopleExposeds).Where(x => x.RiskAssessmentId == raId);
var peopleExp = from c in cmPeopleExp
join d in db.PeopleExposeds
on c.PeopleExposedId equals d.PeopleExposedId
orderby d.Name
select new RAPeopleExp
{
RAPeopleExpId = c.PeopleExposedId,
PeopleExpId = c.PeopleExposedId,
PeopleExpName = d.Name,
RiskAssessmentId = c.RiskAssessmentId,
ControlMeasureId = c.ControlMeasureId
};
var model = cmcombined.Select(t => new FullControlMeasureListViewModel
{
ControlMeasureId = t.ControlMeasureId,
HazardName = t.HazardName,
LikelihoodId = t.LikelihoodId,
Rating = t.Rating,
SeverityId = t.SeverityId,
Activity = t.Activity,
ExCM = t.ExistingMeasure,
//This section here is where I'm struggling
var PeopleString = new StringBuilder();
foreach (var p in peopleExp)
{
PeopleString.AppendLine(p.PeopleName);
{
PeopleExposed = PeopleString,
});
return PartialView("_ControlMeasureList", model);
}
I know I cant directly put this code in the controller but it does represent what I want to do.

You can't foreach within an object initializer (which is what you're trying to do when instantiating FullControlMeasureListViewModel). You can, however, use a combination of string.Join and peopleExp.Select:
var model = cmcombined.Select(t => new FullControlMeasureListViewModel
{
//other props
PeopleExposed = string.Join(",", peopleExp
.Where(p => p.ControlMeasureId == t.ControlMeasureId)
.Select(p => p.PeopleExpName));
//other props
});

Related

LINQ to Entities does not recognize the method 'StaticMethod' method

I have a code like this:
using (var ws = new WebService())
using (var db = new EntityFrameworkModel())
{
var originalFolders = ws.GetFolders();
foo.folders = originalFolders.Select(c => new FolderType()
{
Id = c.Description,
Items = ws.ListDocs(c.Id)
.Select((d, i) =>
new DocType()
{
Id = StaticMethod(d, c),
Order = i,
SomeValue = db.docs.Single(doc => doc.Id == StaticMethod(d, c)).SomeValue
}
).ToArray()
}).ToArray();
}
But I get a "LINQ to Entities does not recognize the method 'StaticMethod' method, and this method cannot be translated into a store expression" exception. Does exist any way to pass a static value as a parameter? Something like this:
using (var ws = new WebService())
using (var db = new EntityFrameworkModel())
{
var originalFolders = ws.GetFolders();
foo.folders = originalFolders.Select(c => new FolderType()
{
Id = c.Description,
Items = ws.ListDocs(c.Id)
.Select((d, i, string myValue = StaticMethod(d, c)) =>
new DocType()
{
Id = myValue,
Order = i,
SomeValue = db.docs.Single(doc => doc.Id == myValue).SomeValue
}
).ToArray()
}).ToArray();
}
I can't modify DocType class constructor. Does exist any way?
Usually this is a matter of making sure you don't inline functions in linq-to-SQL expressions that can't be turned into valid SQL.
Try this:
using (var ws = new WebService())
using (var db = new EntityFrameworkModel())
{
var originalFolders = ws.GetFolders();
foo.folders = originalFolders.Select(c => new FolderType()
{
Id = c.Description,
Items = ws.ListDocs(c.Id)
.Select((d, i) =>
{
var id = StaticMethod(d, c);
return new DocType()
{
Id = id,
Order = i,
SomeValue = db.docs.Single(doc => doc.Id == id).SomeValue
};
}).ToArray()
}).ToArray();
}

Create objects into model foreach query

I have a simple model like:
public class StatisticsModel
{
public Guid TaskId { get; set; }
public string Name { get; set; }
public int Time {get; set; }
}
Now I want to add to that model each register of foreach clause like:
StatisticsModel model = new StatisticsModel();
foreach(var i in tasks)
{
var parameters = ToDataTable(tasks.Select(x => new { i.TaskId, i.Name }).ToList());
var timeOfTasks = db.ExeSQLParamTable("usp_Get_WorkedProyectTime", parameters, "#ProjectTimeWorkedTableType");
var test = (from DataRow dr in timeOfTasks.Rows select (int)dr["TaskName"]).FirstOrDefault();
model.TaskId = i.TaskId;
model.Name = i.Name;
model.Time = test
}
var final2 = model;
So as you can see I assign TaskId, Name and Time to model, but when foreach finish it only add last register to model. How can I create one object foreach task(in my case) in model? I try something like model.Add()but add method donesn't exists in my model. What am I doing wrong? Regards
You're close, you just need a list of models:
List<StatisticsModel> models = new List<StatisticsModel>();
foreach(var i in tasks)
{
StaticsModel model = new StatisticsModel();
var parameters = ToDataTable(tasks.Select(x => new { i.TaskId, i.Name }).ToList());
var timeOfTasks = db.ExeSQLParamTable("usp_Get_WorkedProyectTime", parameters, "#ProjectTimeWorkedTableType");
var test = (from DataRow dr in timeOfTasks.Rows select (int)dr["TaskName"]).FirstOrDefault();
model.TaskId = i.TaskId;
model.Name = i.Name;
model.Time = test;
models.Add(model);
}
You can't add multiple attributes to a single thing: you must have multiple StatisticsModel objects for this.
For example, you could use a List<StatisticsModel>:
var models = List<StatisticsModel>();
foreach(var i in tasks) {
StatisticsModel model = new StatisticsModel();
var parameters = ToDataTable(tasks.Select(x => new { i.TaskId, i.Name }).ToList());
var timeOfTasks = db.ExeSQLParamTable("usp_Get_WorkedProyectTime", parameters, "#ProjectTimeWorkedTableType");
var test = (from DataRow dr in timeOfTasks.Rows select (int)dr["TaskName"]).FirstOrDefault();
model.TaskId = i.TaskId;
model.Name = i.Name;
model.Time = test;
models.Add(model);
}
If you prefer LINQ-style queries, you could eliminate the loop altogether:
var models = tasks.Select(i => {
var parameters = ToDataTable(tasks.Select(x => new { i.TaskId, i.Name }).ToList());
var timeOfTasks = db.ExeSQLParamTable("usp_Get_WorkedProyectTime", parameters, "#ProjectTimeWorkedTableType");
var test = (from DataRow dr in timeOfTasks.Rows select (int)dr["TaskName"]).FirstOrDefault();
return new StatisticsModel {
TaskId = i.TaskId
, Name = i.Name
, Time = test
};
}).ToList();
Sounds like you need a List<StatisticsModel> at the top, that way you can add to it in your foreach:
List<StatisticsModel> models = new List<StatisticsModel>();
foreach(...)
{
...
StatisticsModel model = new StatisticsModel();
// Assign props
models.Add(model);
}
Or even better; since you are actually just transforming the task collection, just use a select:
List<StatisticsModel> models = tasks.Select(task => {
//The foreach contents
StatisticsModel model = new StatisticsModel();
// Assign props
return model;
}).ToList(); //ToList not necessary; eager enumeration is not ideal most of the time but included since you seem to want a list
Each iteration of your foreach loop overwrites the model. Store it in a List:
List<StatisticsModel> allModels = new List<StatisticsModel>();
foreach(var i in tasks)
{
StatisticsModel model = new StatisticsModel();
var parameters = ToDataTable(tasks.Select(x => new { i.TaskId, i.Name }).ToList());
var timeOfTasks = db.ExeSQLParamTable("usp_Get_WorkedProyectTime", parameters, "#ProjectTimeWorkedTableType");
var test = (from DataRow dr in timeOfTasks.Rows select (int)dr["TaskName"]).FirstOrDefault();
model.TaskId = i.TaskId;
model.Name = i.Name;
model.Time = test
allModels.Add(model);
}
var final2 = allModels;
you need to create a list (or some other collection) to get a list of the models. Here's the code below
List<StatisticsModel> models = new List<StatisticsModel>();
foreach(var i in tasks)
{
var parameters = ToDataTable(tasks.Select(x => new { i.TaskId, i.Name }).ToList());
var timeOfTasks = db.ExeSQLParamTable("usp_Get_WorkedProyectTime", parameters, "#ProjectTimeWorkedTableType");
var test = (from DataRow dr in timeOfTasks.Rows select (int)dr["TaskName"]).FirstOrDefault();
StatisticsModel model = new StatisticsModel();
model.TaskId = i.TaskId;
model.Name = i.Name;
model.Time = test
models.Add(model);
}
var final2 = models; //list of model

How to sort in LINQ If Join other database

Sort in LINQ
I have 2 database CustomerEntities and BillEntities
I want to get CustomerName from CustomerEntities and sort it but it have no data and I want .ToList() just once time because it slow if used many .ToList()
using (var db1 = new CustomerEntities())
{ using (var db2 = new BillEntities())
{
var CustomerData = db1.Customer.Select(s=> new{s.CustomerCode,s.CustomerName}).ToList();
var BillData = (from t1 in db2.Bill
select new {
BillCode = t1.Billcode,
CustomerCode = t1.Customer,
CustomerName = ""; //have no data
});
}
if(sorting.status==true)
{
BillData= BillData.OrderBy(o=>o.CustomerName); //can't sort because CustomerName have no data
}
var data = BillData .Skip(sorting.start).Take(sorting.length).ToList(); // I want .ToList() just once time because it slow if used many .ToList()
foreach (var b in data)
{
var Customer = CustomerData.FirstOrDefault(f => f.CustomerCode==b.CustomerCode );
if(CustomerName>!=null)
{
r.CustomerName = Customer.CustomerName; //loop add data CustomerName
}
}
}
I have no idea to do it. Help me please
I'm not sure if I understand your code but what about this:
var BillData = (from t1 in db2.Bill
select new {
BillCode = t1.Billcode,
CustomerCode = t1.Customer,
CustomerName = db1.Customer.FirstOrDefault(c => c.CustormerCode == t1.Customer)?.CustomerName
});
Then you have objects in BillData that holds the CustomerName and you can order by that:
BillData.OrderBy(bd => bd.CustomerName);
If you just want to get CustomerName from your customer Db and sort it, this is what i would have used. I used orderByDescending but you can use OrderBy aswell.
public List<Customer> getLogsByCustomerName(string customername)
{
using (var dbentites = new CustomerEntities())
{
var result = (from res in dbentites.Customer.OrderByDescending(_ => _.CustomerName)
where res.CustomerName == customername
select res).ToList();
return result.ToList();
}
}

Check for missing elements while using LINQ to XML

I am trying get data from the xml. Below is the code which
gets data from the XDocument and return list<t>.
However, p.Element("Sponsor") can sometimes be null. How can I check for the null values
var atClauseList = doc.Descendants(CLAUSE_GROUP_TAG).Descendants(AT_CLAUSE_TAG).Select(p => new AtClause()
{
ClauseNumber = (string)p.Element("Number"),
Sponsors = p.Element("Sponsor").Elements(SPONSOR_TAG).Select(y => y.Value)
.ToList(),
Page = p.Element("Sponsor").Element("aItem").Element("AmendText").Element("Page").ElementValueNull(),
Line = p.Element("Sponsor").Element("aItem").Element("AmendText").Element("Line").ElementValueNull(),
LineText = p.Element("Sponsor").Element("aItem").Element("AmendText").Nodes().OfType<XText>().FirstOrDefault().XTextValueNull(),
ItalicText = p.Element("Sponsor").Element("aItem").Element("AmendText").Element("Italic").ElementValueNull(),
ParaList = p.Element("Sponsor").Element("aItem").Element("AmendText").Elements("Para").Select(L => new Para
{
ParaText = (string)L,
Number = ((System.Xml.Linq.XElement)(L)).AttributeValueNull("Number"),
Quote = ((System.Xml.Linq.XElement)(L)).AttributeValueNull("Quote"),
}
).ToList()
}).ToList();
move your code out of an object initializer, and add some logic to it:
var atClauseList = new List<AtClause>();
foreach(var item in doc.Descendants(CLAUSE_GROUP_TAG).Descendants(AT_CLAUSE_TAG))
{
var atClause = new AtClause();
atClause.ClauseNumber = (string)item.Element("Number");
var sponsor = item.Element("Sponsor");
if (sponsor != null)
{
atClause.Sponsors = sponsor.Elements(SPONSOR_TAG).Select(y => y.Value).ToList();
atClause.Page = sponsor.Element("aItem").Element("AmendText").Element("Page").ElementValueNull();
atClause.Line = sponsor.Element("aItem").Element("AmendText").Element("Line").ElementValueNull();
atClause.LineText = sponsor.Element("aItem").Element("AmendText").Nodes().OfType<XText>().FirstOrDefault().XTextValueNull();
atClause.ItalicText = sponsor.Element("aItem").Element("AmendText").Element("Italic").ElementValueNull();
atClause.ParaList = sponsor.Element("aItem").Element("AmendText").Elements("Para").Select(L => new Para
{
ParaText = (string)L,
Number = ((System.Xml.Linq.XElement)(L)).AttributeValueNull("Number"),
Quote = ((System.Xml.Linq.XElement)(L)).AttributeValueNull("Quote"),
}).ToList();
atClauseList.Add(atClause);
}
You can use sequences rather than leaving the IEnumerable immediately:
var value = (string)p.Elements("Sponsor")
.Elements("aItem")
.Elements("AmendText")
.Elements("Page")
.SingleOrDefault()

How can I save a viewmodel for postback viewing?

I am working on MVC project where I have successfully created a search page with several dropdowns and textboxes. After the user queries the data, they are then transferred to a List page with a list of results corresponding to our search. I was wondering if it is possible to create a button located on the List view that returns them back to the search page, the search page's textboxes/dropdowns still populated with their previous search. Currently, when they return, their previous search was cleared, and they can't see what was queried.
Simplified: Is there a way to capture the data of a viewmodel on query submit, and then be able to access it with simple return button.
Get Method (populates dropdown etc)
[HttpGet]
public ActionResult Index()
{
//testTypes
var testTypesL = new List<string>();
var testTypesQr = from z in db.Results
orderby z.TestType
select z.TestType;
testTypesL.AddRange(testTypesQr.Distinct());
//technicians
var techniciansL = new List<string>();
var techniciansQr = from z in db.Results
orderby z.Technician
select z.Technician;
techniciansL.AddRange(techniciansQr.Distinct());
//engineers
var engineersL = new List<string>();
var engineerQr = from z in db.Results
orderby z.Engineer
select z.Engineer;
engineersL.AddRange(engineerQr.Distinct());
//testStalls
var testStallL = new List<string>();
var testStallQr = from z in db.Results
orderby z.TestStall
select z.TestStall;
testStallL.AddRange(testStallQr.Distinct());
//unit models
var unitModelL = new List<string>();
var unitModelQr = from z in db.Results
orderby z.UnitID
select z.UnitID;
unitModelL.AddRange(unitModelQr.Distinct());
TestDataViewModel obj = new TestDataViewModel();
obj.EngineerList = new SelectList(engineersL);
obj.TechnicianList = new SelectList(techniciansL);
obj.TestStallList = new SelectList(testStallL);
obj.UnitModelList = new SelectList(unitModelL);
obj.TestTypeList = new SelectList(testTypesL);
return View("Index", obj);
}
Post Method: (sends user query to the List view)
[HttpPost]
public ActionResult Index(TestDataViewModel obj)
{
var data = from d in db.Results
select d;
//search data parameters
if (!String.IsNullOrEmpty(obj.StartDate.ToString()) && !String.IsNullOrEmpty (obj.EndDate.ToString()))
{
data = data.Where(z => obj.StartDate <= z.EndDate && obj.EndDate >= z.EndDate);
}
if (!String.IsNullOrEmpty(obj.TestNumber.ToString()))
{
data = data.Where(z => z.TestNumber == obj.TestNumber);
}
if (!String.IsNullOrEmpty(obj.unitModel))
{
data = data.Where(z => z.UnitID == obj.unitModel);
}
if (!String.IsNullOrEmpty(obj.Project))
{
data = data.Where(z => z.ProjectNum.Contains(obj.Project));
}
if (!String.IsNullOrEmpty(obj.testType))
{
data = data.Where(z => z.TestType == obj.testType);
}
if (!String.IsNullOrEmpty(obj.engineer))
{
data = data.Where(z => z.Engineer == obj.engineer);
}
if (!String.IsNullOrEmpty(obj.technician))
{
data = data.Where(z => z.Technician == obj.technician);
}
if (!String.IsNullOrEmpty(obj.testStall))
{
data = data.Where(z => z.TestStall == obj.testStall);
}
return View("List", data);
}

Categories

Resources