Create List from Another List in MVC - linq

I have one list populated from Database with properties code_type , description , min_value, max_value, id etc
I want to create another lists from list 1 with filter condition value of code_type with only three properties
i.e description , min_value, & max value (code_type is not required). This revised list will be used for to bind View in MVC
\Kindly help for the same
Below is my code for the same. If code ="04" Then populate list for caste & so on. Can I Use Linq for the same?
public class MyPrefernce
{
public string memberid { get; set; }
public string code { get; set; }
public string description { get; set; }
public long? min_value { get; set; }
public long? max_value { get; set; }
public long? sysid { get; set; }
public string isChecked { get; set; }
public List<Caste> lcaste;
public List<MyPrefernce> getPrefence(long sysmemberid, string memberid)
{
List<MyPrefernce> lstObj = new List<MyPrefernce>();
string strQuery = "proc_Get_Member_Preference";
Connection cobj = new Connection();
string strConnection = cobj.getConnectionString();
SqlConnection con = new SqlConnection(strConnection);
con.Open();
SqlCommand cmd = new SqlCommand(strQuery, con);
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.AddWithValue("#nSysMemberId", sysmemberid);
SqlDataAdapter ada = new SqlDataAdapter(cmd);
DataSet ds = new DataSet();
ada.Fill(ds);
if (ds.Tables[0].Rows.Count > 0)
{
for (int i = 0; i < ds.Tables[0].Rows.Count; i++)
{
MyPrefernce obj = new MyPrefernce();
obj.code = ds.Tables[0].Rows[i]["code"].ToString();
obj.isChecked = ds.Tables[0].Rows[i]["isChecked"].ToString();
obj.min_value = Convert.ToInt64(ds.Tables[0].Rows[i]["min_value"]);
obj.max_value = Convert.ToInt64(ds.Tables[0].Rows[i]["max_value"]);
obj.sysid = sysid;
obj.memberid = memberid;
lstObj.Add(obj);
}
}
return lstObj;
}
}
public class Caste
{
public int sysId { get; set; }
public string decription { get; set; }
public string? isChecked { get; set; }
}

You should create a new class, defining the fields you need, and use auto-mapper to map the the fields between classes.

Related

I try to add entity model class data to my another list ,but after foreach Same rows insert in every row , MVC

This is my Entity model class which was auto generated by Ado.net model
public partial class SubModule
{
public int SubModuleId { get; set; }
public Nullable<int> ModuleId { get; set; }
public string SubModuleName { get; set; }
public Nullable<bool> Active { get; set; }
public Nullable<bool> IsModules { get; set; }
public string url { get; set; }
public string path { get; set; }
public string subform { get; set; }
}
this is my another class
public class ChildModules
{
public int ? SubModuleId { get; set; }
public Nullable<int> ModuleId { get; set; }
public string SubModuleName { get; set; }
public Nullable<bool> Active { get; set; }
public Nullable<bool> IsModules { get; set; }
public string url { get; set; }
public string path { get; set; }
public string subform { get; set; }
}
I want to copy Sub modules data to my Child modules class properties
My code is
List<SubModule> ChildModule = entity.SubModules.Where(x => x.IsModules == false).ToList();
List<ChildModules> listchildmodules = new List<ChildModules>();
ChildModules chmodule = new ChildModules();
foreach (SubModule mod in ChildModule)
{
chmodule.SubModuleId = mod.SubModuleId;
chmodule.ModuleId = mod.ModuleId;
chmodule.SubModuleName = mod.SubModuleName;
chmodule.Active = mod.Active;
chmodule.IsModules = mod.IsModules;
chmodule.url = mod.url;
chmodule.path = mod.path;
chmodule.subform = mod.subform;
listchildmodules.Add(chmodule);
}
but in listchildmodules last row insert in every index.
Why?
Your code always add the same object always. Because you always updating the values of same object and insert that into list.
Keep the below line of code inside foreach.
ChildModules chmodule = new ChildModules();
Your foreach should look like below
foreach (SubModule mod in ChildModule)
{
ChildModules chmodule = new ChildModules();
chmodule.SubModuleId = mod.SubModuleId;
chmodule.ModuleId = mod.ModuleId;
chmodule.SubModuleName = mod.SubModuleName;
chmodule.Active = mod.Active;
chmodule.IsModules = mod.IsModules;
chmodule.url = mod.url;
chmodule.path = mod.path;
chmodule.subform = mod.subform;
listchildmodules.Add(chmodule);
}
Or you could declare ChildModules chmodule; outside foreach and initialize chmodule = new ChildModules(); inside foreach loop.

Max value LINQ using class

I've got this class
public class Materiale
{
public string IdMateriale { get; set; }
public string GenereMateriale { get; set; }
public string Categoria { get; set; }
public string Modello { get; set; }
public string Tipo { get; set; }
public string NumSerie { get; set; }
public int Anno { get; set; }
public string DittaCostruttrice { get; set; }
public string Note { get; set; }
public List<Controllo> Controlli = new List<Controllo>();
}
public class Controllo
{
public string IdControllo { get; set; }
public DateTime DataControllo { get; set; }
public string IdMateriale { get; set; }
public string Utente { get; set; }
public string Stato { get; set; }
public string Note { get; set; }
}
I want to query a list of "Materiale" filtering "Controlli". I need to retrieve all properties of the "Materiale" class and only one property of the "Controllo" class (the one named "Stato"). From the list "Controlli" I need the one that has the most recent "DataControllo" property.
I try this in a LINQ query but I receive an error (Max doesn't exist in the current context)
List<Materiale> m = new List<Materiale>();
List<Materiale> m2 = (from ma in m
from c in ma.Controlli
where c.DataControllo == Max(c.DataControllo)
select new
{
ma, c.Stato
}).ToList();
Can someone help me
#Christos is correct, here is my version with let in query syntax:-
List<Materiale> m2 = from m in MaterialeList
let RecentControllo = m.OrderByDescending(x => x.DataControllo)
.FirstOrDefault()
select new Materiale
{
IdMateriale = m.IdMateriale,
GenereMateriale = m.GenereMateriale,
//Similarily other properties of Materiale here
Stato = RecentControllo != null ? RecentControllo.Stato : ""
}).ToList();
I think that you need something more simple like the following one:
List<Materiale> m2 = from ma in m
let mostRecentControllo = ma.Controlli
.OrderByDescending(c=>c.DataControllo)
.FirstOrDefault()
select new
{
Materiale = ma,
Stato = mostRecentControllo != null
? mostRecentControllo.Stato : null
}).ToList();
I have supposed that each Materiale's Controlli list contains Controllo with the same IdMateriale.

Troubleshoot object reference error when filling mvc models with datareader?

I am using MVC 3 and I am using a datareader to create a list of items that have subItems. When I add the subitem I get "Object reference not set to an instance of an object." With the following code:
QuestionaireLine question = new QuestionaireLine();
question.Question_ID = Convert.ToInt32(reader["Question_ID"]);
question.Question_Answer = reader["Question_Answer"].ToString();
...etc..
currentGroup.Lines.Add(question); //exception thrown here
The models:
public class Questionaire
{
public int Question_Group_Id { get; set; }
public string Question_Group_Name { get; set; }
public int Question_Group_Indent { get; set; }
public int Question_Group_Order { get; set; }
public List<QuestionaireLine> Lines { get; set; }
}
public class QuestionaireLine
{
public int Question_ID { get; set; }
public string Question_Label { get; set; }
public string Question_Answer { get; set; }
public int Data_Type { get; set; }
public int Control_Type { get; set; }
public string Data_Choices { get; set; }
public int Data_Max_Length { get; set; }
public bool Issue_Tagged { get; set; }
public int Question_Order { get; set; }
public string NumberedQuestion
{
get { return String.Format("{0}. {1}", Question_Order, Question_Label); }
}
}
The whole code:
// what am I missing??
using (var conn = new SqlConnection(_connectionString))
{
List<Questionaire> groups = new List<Questionaire>();
var com = new SqlCommand();
com.Connection = conn;
com.CommandType = CommandType.StoredProcedure;
com.Parameters.Add(new SqlParameter
{
ParameterName = "#Review_ID",
Value = reviewID
});
com.CommandText = "Review_Get_Question_Groups_Answers";
conn.Open();
// Get the reader
SqlDataReader reader = com.ExecuteReader();
// Process each result in the result set
int currQuestionGroupId = 0;
Questionaire currentGroup = null;
while (reader.Read())
{
var questionGroupId = Convert.ToInt32(reader["Question_Group_Id"]);
if (questionGroupId != currQuestionGroupId)
{
currQuestionGroupId = questionGroupId;
if (currentGroup != null)
{
groups.Add(currentGroup);
}
currentGroup = new Questionaire();
currentGroup.Question_Group_Id = Convert.ToInt32(reader["Question_Group_Id"]);
currentGroup.Question_Group_Indent = Convert.ToInt32(reader["Question_Group_Indent"]);
currentGroup.Question_Group_Name = reader["Question_Group_Name"].ToString();
currentGroup.Question_Group_Order = Convert.ToInt32(reader["Question_Group_Order"]);
}
if (reader["Question_ID"] != DBNull.Value)
{
QuestionaireLine question = new QuestionaireLine();
question.Question_ID = Convert.ToInt32(reader["Question_ID"]);
question.Question_Answer = reader["Question_Answer"].ToString();
question.Issue_Tagged = Convert.ToBoolean(reader["Issue_Tagged"]);
question.Data_Type = Convert.ToInt32(reader["Data_Type"]);
question.Data_Max_Length = Convert.ToInt32(reader["Data_Max_Length"]);
question.Data_Choices = reader["Data_Choices"].ToString();
question.Question_Label = reader["Question_Label"].ToString();
question.Question_Order = Convert.ToInt32(reader["Question_Order"]);
question.Control_Type = Convert.ToInt32(reader["Control_Type"]);
currentGroup.Lines.Add(question);
}
if (currentGroup != null)
{
groups.Add(currentGroup);
}
}
reader.Close();
com.Dispose();
return groups;
}
Your Lines property on your Questionaire instance is Null. Change to:
public class Questionaire
{
public int Question_Group_Id { get; set; }
public string Question_Group_Name { get; set; }
public int Question_Group_Indent { get; set; }
public int Question_Group_Order { get; set; }
public List<QuestionaireLine> Lines { get; set; }
public Questionaire() {
Lines = new List<QuestionaireLine>();
}
b.t.w. stepping through your code would have shown you that.

Linq assign to a List<> List Binding

I'm getting this error at running time:
Exception Details: System.InvalidOperationException: Unhandled binding type: ListBinding
Choice_A, _b,_C are strings
'Choices' is List
var qs = (from questions in dc.Survey_Questions
where questions.Survey_ID == surveyid
select new SQuestions
{
QuestionID = questions.Question_ID,
Description = questions.Description,
Choice_A = questions.Choice_A,
Choice_B = questions.Choice_B,
Choice_C = questions.Choice_C,
**Choices = {questions.Choice_A, questions.Choice_B,
questions.Choice_C}**
}).ToList();
Basically I'd like to know how I assign to List Choices values of Choice_A,Choice_B, Choice_C.
Thanks in advance.
You can try this. If you already have the following two classes
public class Question
{
public int Question_ID { get; set; }
public int Survey_ID { get; set; }
public String Description { get; set; }
public String Choice_A { get; set; }
public String Choice_B { get; set; }
public String Choice_C { get; set; }
}
public class SQuestions
{
public int QuestionID { get; set; }
public String Description { get; set; }
public String Choice_A { get; set; }
public String Choice_B { get; set; }
public String Choice_C { get; set; }
public List<String> Choices { get; set; }
}
Then the LINQ Query will be
var qs = (from question in dc.Survey_Questions
where question.Survey_ID == surveyid
select new SQuestions
{
QuestionID = question.Question_ID,
Description = question.Description,
Choice_A = question.Choice_A,
Choice_B = question.Choice_B,
Choice_C = question.Choice_C,
Choices = new List<string>(new String[] { question.Choice_A,question.Choice_B, question.Choice_C })
}).ToList();
LINQ to Entities does not support this binding syntax. You should be able to do this, though:
qs = (from questions in dc.Survey_Questions
where questions.Survey_ID == surveyid
select new SQuestions
{
QuestionID = questions.Question_ID,
Description = questions.Description,
Choice_A = questions.Choice_A,
Choice_B = questions.Choice_B,
Choice_C = questions.Choice_C,
Choices = new List<string> {questions.Choice_A, questions.Choice_B,
questions.Choice_C}
}).ToList();

Speed up large Linq to Entities call MVC3

Below is the code I am using and the database table it is pulling from has about 92000 records in it. The way it is pulling right now it is pulling all 92000 records then doing the filtering.
What I am looking to do is the filtering on the initial pull from the DB so that it does not take aproximately 40 seconds to load the page.
This is something I am still new at so I am lost as to how to do this and make it work with my view
public ViewResult Makes()
{
var items = (from item in DBCacheHelper.recallslist
orderby item.MFGTXT ascending
select item.ToDomainRecall()).GroupBy(item => item.MFGTXT).Select(grp => grp.First());
return View(items);
}
public static IEnumerable<Recall> recallslist
{
get
{
if (c["GetAllRecalls"] == null)
{
c.Insert("GetAllRecalls", GetAllRecalls());
return (IEnumerable<Recall>)c["GetAllRecalls"];
}
else
{
return (IEnumerable<Recall>)c["GetAllRecalls"];
}
}
}
public static IEnumerable<Recall> GetAllRecalls()
{
using (DealerContext context = new DealerContext())
{
var items = from item in context.recalls.ToList<Recall>()
select item.ToDomainRecall();
return items.ToList<Recall>();
}
}
SELECT
[Extent1].[RecallsId] AS [RecallsId],
[Extent1].[RECORD_ID] AS [RECORD_ID],
[Extent1].[CAMPNO] AS [CAMPNO],
[Extent1].[MAKETXT] AS [MAKETXT],
[Extent1].[MODELTXT] AS [MODELTXT],
[Extent1].[YEARTXT] AS [YEARTXT],
[Extent1].[MFGCAMPNO] AS [MFGCAMPNO],
[Extent1].[COMPNAME] AS [COMPNAME],
[Extent1].[MFGNAME] AS [MFGNAME],
[Extent1].[BGMAN] AS [BGMAN],
[Extent1].[ENDMAN] AS [ENDMAN],
[Extent1].[RCLTYPECD] AS [RCLTYPECD],
[Extent1].[POTAFF] AS [POTAFF],
[Extent1].[ODATE] AS [ODATE],
[Extent1].[INFLUENCED_BY] AS [INFLUENCED_BY],
[Extent1].[MFGTXT] AS [MFGTXT],
[Extent1].[RCDATE] AS [RCDATE],
[Extent1].[DATEA] AS [DATEA],
[Extent1].[RPNO] AS [RPNO],
[Extent1].[FMVSS] AS [FMVSS],
[Extent1].[DESC_DEFECT] AS [DESC_DEFECT],
[Extent1].[CONEQUENCE_DEFECT] AS [CONEQUENCE_DEFECT],
[Extent1].[CORRECTIVE_ACTION] AS [CORRECTIVE_ACTION],
[Extent1].[NOTES] AS [NOTES],
[Extent1].[RCL_CMPT_ID] AS [RCL_CMPT_ID]
FROM [dbo].[Recalls] AS [Extent1]
Update:
Ultimately I would like to only pull records from the Recalls Table where the MFGTXT is equal to the
MakeName in the AutoMake Table
public class AutoMake
{
[Key]
public int MakeID { get; set; }
public string MakeName { get; set; }
public AutoMake ToDomainAutoMakes()
{
return new AutoMake
{
MakeID = this.MakeID,
MakeName = this.MakeName
};
}
}
public class Recall
{
[Key]
public int RecallsId { get; set; }
public string RECORD_ID { get; set; }
public string CAMPNO { get; set; }
public string MAKETXT { get; set; }
public string MODELTXT { get; set; }
public string YEARTXT { get; set; }
public string MFGCAMPNO { get; set; }
public string COMPNAME { get; set; }
public string MFGNAME { get; set; }
public string BGMAN { get; set; }
public string ENDMAN { get; set; }
public string RCLTYPECD { get; set; }
public string POTAFF { get; set; }
public string ODATE { get; set; }
public string INFLUENCED_BY { get; set; }
public string MFGTXT { get; set; }
public string RCDATE { get; set; }
public string DATEA { get; set; }
public string RPNO { get; set; }
public string FMVSS { get; set; }
public string DESC_DEFECT { get; set; }
public string CONEQUENCE_DEFECT { get; set; }
public string CORRECTIVE_ACTION { get; set; }
public string NOTES { get; set; }
public string RCL_CMPT_ID { get; set; }
public Recall ToDomainRecall()
{
return new Recall
{
RECORD_ID = this.RECORD_ID,
CAMPNO = this.CAMPNO,
MAKETXT = this.MAKETXT,
MODELTXT = this.MODELTXT,
YEARTXT = this.YEARTXT,
MFGCAMPNO = this.MFGCAMPNO,
COMPNAME = this.COMPNAME,
MFGNAME = this.MFGNAME,
BGMAN = this.BGMAN,
ENDMAN = this.ENDMAN,
RCLTYPECD = this.RCLTYPECD,
POTAFF = this.POTAFF,
ODATE = this.ODATE,
INFLUENCED_BY = this.INFLUENCED_BY,
MFGTXT = this.MFGTXT,
RCDATE = this.RCDATE,
DATEA = this.DATEA,
RPNO = this.RPNO,
FMVSS = this.FMVSS,
DESC_DEFECT = this.DESC_DEFECT,
CONEQUENCE_DEFECT = this.CONEQUENCE_DEFECT,
CORRECTIVE_ACTION = this.CORRECTIVE_ACTION,
NOTES = this.NOTES,
RCL_CMPT_ID = this.RCL_CMPT_ID
};
}
}
If you want to add server side filtering outside of your repository methods, you need to return your types as IQueryable rather than IEnumerable and not call .ToList, .AsEnumerable, or any other method that would cause .GetEnumerator to be called. Additionally, your cast `(IEnumerable)c["GetAllRecalls"];' forces LINQ to Objects to be used for subsequent requests rather than retaining the expression tree and using Entity Framework. That being said, you may need to move your call to ToDomainRecall method to after the additional filter is applied as well because that can't be translated to your database. Here are some of the changes you would need to make:
public ViewResult Makes()
{
var items = (from item in DBCacheHelper.recallslist
orderby item.MFGTXT ascending
select item.ToDomainRecall()).GroupBy(item => item.MFGTXT).Select(grp => grp.First());
return View(items);
}
public static IQueryable<Recall> recallslist
{
get
{
if (c["GetAllRecalls"] == null)
{
c.Insert("GetAllRecalls", GetAllRecalls(context));
}
return c["GetAllRecalls"];
}
}
public static IQueryable<Recall> GetAllRecalls(DealerContext context)
{
var items = context.recalls;
return items;
}
Looks like your DBaccess is done in the call to DBCacheHelper.recallslist.
You need to edit the sql that runs from/in this function.
As Eranga pointed out, you don't show how you are filtering the large number down to a smaller number of records. I assume you want 20 or 100 at a time? If so, please see the accepted answer here:
efficient way to implement paging
Specifically, this part which shows how to only retrieve rows x to y (where x = #p0 + 1 AND y = #p0 + #p1):
SELECT [t1].[CodCity],
[t1].[CodCountry],
[t1].[CodRegion],
[t1].[Name],
[t1].[Code]
FROM (
SELECT ROW_NUMBER() OVER (
ORDER BY [t0].[CodCity],
[t0].[CodCountry],
[t0].[CodRegion],
[t0].[Name],
[t0].[Code]) AS [ROW_NUMBER],
[t0].[CodCity],
[t0].[CodCountry],
[t0].[CodRegion],
[t0].[Name],
[t0].[Code]
FROM [dbo].[MtCity] AS [t0]
) AS [t1]
WHERE [t1].[ROW_NUMBER] BETWEEN #p0 + 1 AND #p0 + #p1
ORDER BY [t1].[ROW_NUMBER]

Resources