How do I access list inside an object [closed] - c#

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 9 years ago.
Improve this question
How can I read the values inside H_N1_N2,H_N1_N3,H_N1_N4 that calls from H_N1_N1.
My objective is to put all the values into List that contains another object inside.
The requirement is to eliminate the current process which is storing the values to temp table in database before validation. After validated, it goes to the physical table.
Here's my entities:
public class H_N1_N1
{
public string N101_EntityIdentifierCode { get; set; }
public string N102_Name { get; set; }
public string N103_IdentificationCodeQualifier { get; set; }
public string N104_IdentificationCode { get; set; }
public H_N1_N1()
{
ListH_N1_N2 = new List<H_N1_N2>();
ListH_N1_N3 = new List<H_N1_N3>();
ListH_N1_N4 = new List<H_N1_N4>();
}
public List<H_N1_N2> ListH_N1_N2 { get; set; }
public List<H_N1_N3> ListH_N1_N3 { get; set; }
public List<H_N1_N4> ListH_N1_N4 { get; set; }
}
public class H_N1_N2
{
public string N201_Name01 { get; set; }
public string N202_Name02 { get; set; }
}
public class H_N1_N3
{
public string N301_AddressInformation01 { get; set; }
public string N302_AddressInformation02 { get; set; }
}
public class H_N1_N4
{
public string N401_CityName { get; set; }
public string N402_StateProvinceCode { get; set; }
public string N403_PostalCode { get; set; }
public string N404_CountryCode { get; set; }
}
Here's how I populate my object:
var N1_N1 = dal.GetModelDetails(11);
for (int i = 0; i < Convert.ToInt16(N1_N1.MaxLoop); i++)
{
H_N1_N1 oH_N1_N1 = new H_N1_N1();
stElements = ResizeArray(stElements.Count(), stElements, "H_N1_N1");
oH_N1_N1.N101_EntityIdentifierCode = stElements[1];
oH_N1_N1.N102_Name = stElements[2];
oH_N1_N1.N103_IdentificationCodeQualifier = stElements[3];
oH_N1_N1.N104_IdentificationCode = stElements[4];
objH_N1_N1.Add(oH_N1_N1);
var N1_N2 = dal.GetModelDetails(12);
H_N1_N2 oH_N1_N2 = new H_N1_N2();
stElements = ResizeArray(stElements.Count(), stElements, "H_N1_N2");
oH_N1_N2.N201_Name01 = stElements[1];
oH_N1_N2.N202_Name02 = stElements[2];
oH_N1_N1.ListH_N1_N2.Add(oH_N1_N2);
var N1_N3 = dal.GetModelDetails(14);
H_N1_N3 oH_N1_N3 = new H_N1_N3();
stElements = ResizeArray(stElements.Count(), stElements, "H_N1_N3");
oH_N1_N3.N301_AddressInformation01 = stElements[1];
oH_N1_N3.N302_AddressInformation02 = stElements[2];
oH_N1_N1.ListH_N1_N3.Add(oH_N1_N3);
var N1_N4 = dal.GetModelDetails(16);
H_N1_N4 oH_N1_N4 = new H_N1_N4();
stElements = ResizeArray(stElements.Count(), stElements, "H_N1_N4");
oH_N1_N4.N401_CityName = stElements[1];
oH_N1_N4.N402_StateProvinceCode = stElements[2];
oH_N1_N4.N403_PostalCode = stElements[3];
oH_N1_N4.N404_CountryCode = stElements[4];
}
There's the part where I cannot read the object:
foreach (var oH_N1_N1 in objH_N1_N1)
{
MessageBox.Show(
// Print N1
oH_N1_N1.N101_EntityIdentifierCode
+ "\n" + oH_N1_N1.N102_Name
+ "\n" + oH_N1_N1.N103_IdentificationCodeQualifier
+ "\n" + oH_N1_N1.N104_IdentificationCode
// Print N2
oH_N1_N1.ListH_N1_N2.N201_Name01 //ERROR HERE
+"\n" + oH_N1_N1.ListH_N1_N2.N201_Name02 //ERROR HERE
// Print N3
oH_N1_N1.ListH_N1_N3.N301_AddressInformation01 //ERROR HERE
+"\n" + oH_N1_N1.ListH_N1_N3.N301_AddressInformation02 //ERROR HERE
// Print N4
oH_N1_N1.ListH_N1_N4.N401_CityName //ERROR HERE
+"\n" + oH_N1_N1.ListH_N1_N4.N402_StateProvinceCode //ERROR HERE
+"\n" + oH_N1_N1.ListH_N1_N4.N403_PostalCode //ERROR HERE
+"\n" + oH_N1_N1.ListH_N1_N4.N404_CountryCode //ERROR HERE
);
}
This is what i am trying to do:
N1_somedata
N1_somedata
N1_somedata
N1_somedata
N2_somedata
N2_somedata
N3_somedata
N3_somedata
N4_somedata
N4_somedata
N4_somedata
N4_somedata
N1_somedata
N1_somedata
N1_somedata
N1_somedata
N2_somedata
N2_somedata
N3_somedata
N3_somedata
N4_somedata
N4_somedata
N4_somedata
N4_somedata
N1_somedata
N1_somedata
N1_somedata
N1_somedata
N2_somedata
N2_somedata
N3_somedata
N3_somedata
N4_somedata
N4_somedata
N4_somedata
N4_somedata
Thanks in advance!

OP, this code makes me want to weep for little children, but the reason you're getting errors is because you're placing 4 separate variables in MessageBox.Show() call and not tying them together.
Update
Based on your comment,
when I try to type oH_N1_N1.ListH_N1_N2, there is no N201_Name01 and N201_Name02
That's because oH_N1_N1.ListH_N1_N2 is a List<H_N1_N2> property. You cannot access properties of H_N1_N2 that way. You have to access via the list, for example using the indexer:
oH_N1_N1.ListH_N1_N2[0].N201_Name01
You can also do foreach to get all of the elements...
string crazyNames = string.Empty;
foreach(var crazyName in oH_N1_N1.ListH_N1_N2)
{
crazyNames += crazyName.N201_Name01 + " " + N201_Name02 // etc.
}
Notice the [0] above which is the first element in the list. Now, the intellisense will show you available properties of the stored object, which is an instance of H_N1_N2 and will contain the property N201_Name01 and so on.
Original issue / answer:
Add + signs there and it'll work.
For the love of humanity please use some different naming conventions!
foreach (var oH_N1_N1 in objH_N1_N1)
{
MessageBox.Show(
// Print N1
oH_N1_N1.N101_EntityIdentifierCode
+ "\n" + oH_N1_N1.N102_Name
+ "\n" + oH_N1_N1.N103_IdentificationCodeQualifier
+ "\n" + oH_N1_N1.N104_IdentificationCode
+ // concatenate next object to first one
// Print N2
oH_N1_N1.ListH_N1_N2.N201_Name01 //ERROR HERE
+"\n" + oH_N1_N1.ListH_N1_N2.N201_Name02 //ERROR HERE
+ // concatenate next object to first+second one
// Print N3
oH_N1_N1.ListH_N1_N3.N301_AddressInformation01 //ERROR HERE
+"\n" + oH_N1_N1.ListH_N1_N3.N301_AddressInformation02 //ERROR HERE
+ // concatenate last object to first+second+third one
// Print N4
oH_N1_N1.ListH_N1_N4.N401_CityName //ERROR HERE
+"\n" + oH_N1_N1.ListH_N1_N4.N402_StateProvinceCode //ERROR HERE
+"\n" + oH_N1_N1.ListH_N1_N4.N403_PostalCode //ERROR HERE
+"\n" + oH_N1_N1.ListH_N1_N4.N404_CountryCode //ERROR HERE
);
}

Related

Set DeserializeObject in anonymous property of a class

I have this:
public class ComponentData
{
public dynamic CdHtml { get; set; }
public dynamic CdJson { get; set; }
public dynamic CdSection { get; set; }
public dynamic CdContainer { get; set; }
public dynamic CdRow { get; set; }
public dynamic CdContainerId { get; set; }
public dynamic CdColsJson { get; set; }
}
And i want to set the ComponentData Class with these values but i get an error:
var componentData = new ComponentData()
{
CdHtml = obj.htmlCD,
CdJson = JsonConvert.DeserializeObject<dynamic>(obj.jsonCD),
CdContainerId = "SECTION" + obj.CD_Container_Id,
CdSection = JsonConvert.DeserializeObject<dynamic>(pc.Build_CDxxxJson("xxx" + obj.CD_Container_Id, "width:" + tlj.width.ToString() + "%;padding-left:30px;padding-right:30px;padding-top:30px;padding-bottom:30px;" + sectionCenterStyle, "section")),
CdContainer = JsonConvert.DeserializeObject<dynamic>(pc.Build_CDxxxJson("xxx" + obj.divGUID2, containerStyle, "container")),
CdRow = JsonConvert.DeserializeObject<dynamic>(pc.Build_CDxxxJson("xxx" + obj.divGUID3, "", "row")),
CdColsJson = JsonConvert.DeserializeObject<dynamic>(pc.Build_CDxxxJson(obj.divGUID4, "", string.Format("col-xs-{0} col-sm-{1} col-md-{2} col-lg-{3} hoversel colregion{4}", bsc.xs, bsc.sm, bsc.md, bsc.lg, obj.divGUID4), bsc.xs, bsc.sm, bsc.md, bsc.lg))
};
return Json(new { componentData = componentData, html = obj.html });
how would i return this class with the json objects inside and pass it back to the client using ajax?
Change your code to this:
var componentData = new ComponentData()
{
CdHtml = obj.htmlCD,
CdJson = JsonConvert.DeserializeObject<ExpandoObject>(obj.jsonCD),
CdContainerId = "SECTION" + obj.CD_Container_Id,
CdSection = JsonConvert.DeserializeObject<ExpandoObject>(pc.Build_CDxxxJson("xxx" + obj.CD_Container_Id, "width:" + tlj.width.ToString() + "%;padding-left:30px;padding-right:30px;padding-top:30px;padding-bottom:30px;" + sectionCenterStyle, "section")),
CdContainer = JsonConvert.DeserializeObject<ExpandoObject>(pc.Build_CDxxxJson("xxx" + obj.divGUID2, containerStyle, "container")),
CdRow = JsonConvert.DeserializeObject<ExpandoObject>(pc.Build_CDxxxJson("xxx" + obj.divGUID3, "", "row")),
CdColsJson = JsonConvert.DeserializeObject<ExpandoObject>(pc.Build_CDxxxJson(obj.divGUID4, "", string.Format("col-xs-{0} col-sm-{1} col-md-{2} col-lg-{3} hoversel colregion{4}", bsc.xs, bsc.sm, bsc.md, bsc.lg, obj.divGUID4), bsc.xs, bsc.sm, bsc.md, bsc.lg))
};
If you want to convert to dynamic you need to use ExpandoObject just as you would use when you want to create one with your hands.

Entity to LINQ upload CSV file where single rows can have multiple values in columns

I'm currently working on parsing a csv file that was exported by another application. This application exported the data in a strange way. This export is from accoutning and it looks similar to this..
I'm trying to figure out a way to read the csv file, then split up the multiple 'All Accounts' values and 'Amt' Values so that M200 and 300.89 is another entry, M300 and 400.54 are another entry, and M400 and 100.00 are another entry. So after inserting this single row into the database, I should actually have 4 rows like so..
This is how I'm currently reading and inserting into the database.
List<RawData> data = new List<RawData>();
try
{
string text = File.ReadAllText(lblFileName.Text);
string[] lines = text.Split('\n');
int total = 0, reduced = 0;
foreach (string line in lines)
{
RawData temp = new RawData(line);
total++;
if (!(temp.FirstAccount.Length == 0 || temp.FirstAccount == "1ST-ACCT-NO"))
{
reduced++;
data.Add(temp);
}
}
}
catch (IOException ex)
{
Console.WriteLine("Unable to read file. " + ex.ToString());
MessageBox.Show(ex.ToString());
}
try
{
foreach (RawData rData in data)
{
tCarsInTransit cit = new tCarsInTransit
{
FIRST_ACCT_NO = rData.FirstAccount,
ACCOUNT_NO_DV = rData.AccountNoDv,
ACCT_NO = rData.AcctNo,
ACCT_NO_L = rData.AccNoL,
ACCT_NUM_DV = rData.AcctNumDv,
ACCT_PFX = rData.AcctPfx,
ACCT_PFX_PRT = rData.AcctPfxPrt,
ACCT_TYPE_DV = rData.AcctTypeDv,
ADV_NO = rData.AdvNo,
ALL_PRT_FLAG = rData.AllPrtFlag,
AMT = rData.Amt,
AMT_GLE = rData.AmtGle,
BASE_GLE = rData.BaseGle,
CNT_CAT = rData.CntCat,
COLD_PRT_FLAG = rData.ColdPrtFlag,
COST_DV = rData.CostDv,
COST_OVRD_FLAG_DV = rData.CostOvrdFlagDv,
CR_ACCT_DV = rData.CrAcctDv,
CR_ACCT_DV_GLE = rData.CrAcctDvGle,
CROSS_POSTING_FLAG = rData.CrossPostingFlag,
CROSS_POST_CAT = rData.CrossPostCat,
CTRL_NO = rData.CtrlNo,
CTRL_TYPE_DV = rData.CtrlTypeDv,
DESC_REQD_DV = rData.DescReqdDv,
DR_ACCT_DV = rData.DrAcctDv,
GL_DIST_ACCT_DV = rData.GLDistAcctDv,
GL_DIST_DV = rData.GLDistDv,
GRP_NO_DV = rData.GrpNoDv,
ID_PORT_DATE_TIME_FMT_CAT = rData.IdPortDateTimeFmtCat,
INACTIVITY_DV = rData.InactivityDv,
JOIN_COL = rData.JoinCol,
JRNL_DATE = rData.JrnlDate,
JRNL_PFX = rData.JrnlPfx
};
tCIT.tCarsInTransits.Add(cit);
tCIT.SaveChanges();
lblMessage.ForeColor = System.Drawing.Color.Green;
lblMessage.Text = "Finished uploading. ";
}
}
catch (DbEntityValidationException ex)
{
foreach (var eve in ex.EntityValidationErrors)
{
Console.WriteLine("Entity of type \"{0}\" in state \"{1}\" has the following validation errors:",
eve.Entry.Entity.GetType().Name, eve.Entry.State);
foreach (var ve in eve.ValidationErrors)
{
Console.WriteLine("- Property: \"{0}\", Error: \"{1}\"",
ve.PropertyName, ve.ErrorMessage);
}
}
throw;
}
I am not sure how to accomplish this. The above currently inserts the csv file into Sql Server the exact way the csv file was exported. Any ideas would greatly be appreciated! Thanks!
EDIT: Here is the RawData class.
class RawData
{
public string FirstAccount { get; set; }
public string AccountNoDv { get; set; }
public string AcctNo { get; set; }
public string AccNoL { get; set; }
public string AcctNumDv { get; set; }
public string AcctPfx { get; set; }
public string AcctPfxPrt { get; set; }
public string AcctTypeDv { get; set; }
public string AdvNo { get; set; }
public string AllPrtFlag { get; set; }
public string Amt { get; set; }
public string AmtGle { get; set; }
public string BaseGle { get; set; }
public string CntCat { get; set; }
public string ColdPrtFlag { get; set; }
public string CostDv { get; set; }
public string CostOvrdFlagDv { get; set; }
public string CrAcctDv { get; set; }
public string CrAcctDvGle { get; set; }
public string CrossPostingFlag { get; set; }
public string CrossPostCat { get; set; }
public string CtrlNo { get; set; }
public string CtrlTypeDv { get; set; }
public string DescReqdDv { get; set; }
public string DrAcctDv { get; set; }
public string GLDistAcctDv { get; set; }
public string GLDistDv { get; set; }
public string GrpNoDv { get; set; }
public string IdPortDateTimeFmtCat { get; set; }
public string InactivityDv { get; set; }
public string JoinCol { get; set; }
public string JrnlDate { get; set; }
public string JrnlPfx { get; set; }
public RawData(string csvString)
{
string[] citData = csvString.Replace(", ", "").Replace(".,", ".").Split(',');
try
{
FirstAccount = citData[0];
AccountNoDv = citData[1];
AcctNo = citData[2];
AccNoL = citData[3];
AcctNumDv = citData[4];
AcctPfx = citData[5];
AcctPfxPrt = citData[6];
AcctTypeDv = citData[7];
AdvNo = citData[8];
AllPrtFlag = citData[9];
Amt = citData[10];
AmtGle = citData[11];
BaseGle = citData[12];
CntCat = citData[13];
ColdPrtFlag = citData[14];
CostDv = citData[15];
CostOvrdFlagDv = citData[16];
CrAcctDv = citData[17];
CrAcctDvGle = citData[18];
CrossPostingFlag = citData[19];
CrossPostCat = citData[20];
CtrlNo = citData[21];
CtrlTypeDv = citData[22];
DescReqdDv = citData[23];
DrAcctDv = citData[24];
GLDistAcctDv = citData[25];
GLDistDv = citData[26];
GrpNoDv = citData[27];
IdPortDateTimeFmtCat = citData[28];
InactivityDv = citData[29];
JoinCol = citData[30];
JrnlDate = citData[31];
JrnlPfx = citData[32];
}
catch (Exception ex)
{
Console.WriteLine("Something went wrong. " + ex.ToString());
}
}
}
EDIT 2: AllAccounts in the images is acutally 'AccountNoDv' and there are actually many different fields that have multiples like 'AccountNoDv'(AllAccounts) but we might be removing those as this is not a final export. As of right now the two fields I'm worried most about are AccountNoDv and Amt.
Try something like this:
foreach (string line in lines)
{
RawData temp = new RawData(line);
var AllAccounts = temp.AccountNoDv.split(' ');
var Amts = temp.Amt.split(' ');
if (AllAccounts.Length() == Amts.Length() && Amts.Length() > 1) {
// We have multiple values!
reduced++;
for (int i = 0; i < AllAccounts.Length(); i++) {
RawData temp2 = RawDataCopy(temp); // Copy the RawData object
temp2.AccountNoDv = AllAccounts[i];
temp2.Amt = Amts[i];
total++;
data.Add(temp2);
}
}
else {
total++;
if (!(temp.FirstAccount.Length == 0 || temp.FirstAccount == "1ST-ACCT-NO"))
{
reduced++;
data.Add(temp);
}
}
}
And:
private RawData RawDataCopy(RawData copyfrom) {
// Write a function here that returns an exact copy from the one provided
// You might have to create a parameterless constructor for RawData
RawData RawDataCopy = new RawData();
RawDataCopy.FirstAccount = copyfrom.FirstAccount;
RawDataCopy.AccountNoDv = copyfrom.AccountNoDv;
RawDataCopy.AcctNo = copyfrom.AcctNo;
// . . . . . . . .
RawDataCopy.JrnlPfx = copyfrom.JrnlPfx;
return RawDataCopy;
}
Then also add a parameterless constructor to your RawData class:
public RawData()
{
}
Perhaps it would be sexier to implement the ICloneable interface and call the Clone() function instead of the RawDataCopy function, but it gets the idea across.
In Linq you can use SelectMany to increase the number of elements in a list. Here is a rough example of how this could be done. I make the assumption that the number of sub elements in AllAccounts and Amt is the same. A more robust solution would check for these issues.
So after you have loaded your data list:
var expandedData =
data.SelectMany(item =>
// split amount (will just return one item if no spaces)
item.Amt.Split(" ".ToCharArray())
// join this to the split of all accounts
.Zip(item.AllAccounts.Split(" ".ToCharArray()),
// return the joined item as a new anon object
(a,b) => new { amt=a, all=b }),
// take the original list item and the anon object and return our new item
(full,pair) => { full.Amt = pair.amt; full.AllAccounts = pair.all; return full; }));
You will now have a list of your data items with the multiple items expanded into the list.
I don't have test data to test so I might have some minor typos -- but I put in lots of comments to make the Linq as clear as possible.
Here is is simple example I wrote in LinqPad for myself to make sure I understood how SelectMany worked:
string [] list = { "a b c d","e","f g" };
var result = list.SelectMany((e) =>
e.Split(" ".ToCharArray()),
(o,item) => new { org = o, item = item}).Dump();

Using StreamWriter to write to different files in a Parallel.Foreach

I am attempting to write separate collections to seperate csv in a Parallel.Foreach loop. When I run this, I get the following error:
The process cannot access the file 'C:\temp\OCRProcess\2011\49\OCRProcess-2011-49.csv' because it is being used by another process.
When I look at all the worker processes, they are opening different files, none of them are using the same file location. From what I can tell, each thread (worker process) is not conflicting.
public void GenerateCSVFile(List<CSVFile> csvFiles)
{
Parallel.ForEach(csvFiles, (csvfile, state, index) =>
{
var fileLocation = _storageLocation + csvfile.Type + s + csvfile.Year + s + csvfile.Day + s + csvfile.Type + "-" +
csvfile.Year + "-" + csvfile.Day + ".csv";
if (!File.Exists(fileLocation))
{
File.Create(fileLocation);
}
using (var streamWriter = new StreamWriter(fileLocation))
{
foreach (var csvRecord in csvfile.CSVRecords)
{
streamWriter.WriteLine(csvRecord.Object_Id + "," + csvRecord.DocumentName + "," + csvRecord.BCI_DCN + "," + csvRecord.CreationDate);
}
}
});
}
Here is the CSVFile and CSVRecord classes just incase.
public sealed class CSVRecord
{
public String BCI_DCN { get; set; }
public String Object_Id { get; set; }
public String DocumentName { get; set; }
public String CreationDate { get; set; }
}
public sealed class CSVFile
{
public List<CSVRecord> CSVRecords { get; set; }
public String Year { get; set; }
public String Type { get; set; }
public String Day { get; set; }
public CSVFile()
{
CSVRecords = new List<CSVRecord>();
}
}
The issues is due to File.Create(fileLocation), which returns a FileStream and keeps the file open. When the StreamWriter attempted to open this, it was already open and caused the error.
To correct the problem, removed the following IF statement:
if (!File.Exists(fileLocation))
{
File.Create(fileLocation);
}
And updated the USING statement as followed. By adding the TRUE parameter, it allows StreamWriter to append to the file if it exists, otherwise create it.
using (var streamWriter = new StreamWriter(fileLocation, true))
{
foreach (var csvRecord in csvfile.CSVRecords)
{
streamWriter.WriteLine(csvRecord.Object_Id + "," + csvRecord.DocumentName + "," + csvRecord.BCI_DCN + "," + csvRecord.CreationDate);
}
}

Accessing Data sets from Json

I am mapping JSON data to my own classes in C# and then trying to display various data where I need it however I'm having a small issue where I can't seem to get at data when I believe I should be able to. Obviously something is wrong and I was hoping someone could point me in the right direction:
Example snippet of JSON:
"items"
{
"0"
{
"name" "Riki's Dagger"
"prefab" "default_item"
"item_name" "#DOTA_Item_Rikis_Dagger"
"item_type_name" "#DOTA_WearableType_Daggers"
"model_player" "models/heroes/rikimaru/rikimaru_weapon.mdl"
"used_by_heroes"
{
"npc_dota_hero_riki" "1"
}
}
"1"
{
"name" "Anti-Mage's Glaive"
"prefab" "default_item"
"item_description" "#DOTA_Item_Desc_AntiMages_Glaives"
"item_name" "#DOTA_Item_AntiMages_Glaive"
"item_type_name" "#DOTA_WearableType_Glaive"
"model_player" "models/heroes/antimage/antimage_weapon.mdl"
"used_by_heroes"
{
"npc_dota_hero_antimage" "1"
}
}
I am using the following to serialize this to my own classes as follows:
DotaItemsGameResult itemGameResult
= JsonConvert.DeserializeObject<DotaItemsGameResult>(rawItemDetailsJson);
This is working OK as I have used this elsewhere.
The trouble comes here:
string dataToDisplay = "";
foreach (DotaItemsGameItem item in itemGameResult.Items_Game.Items.Item_Index)
{
dataToDisplay += "<h3> Item: " + item.Name + "</h3>";
dataToDisplay += "<p> Quality: " + item.Item_Quality + "</p>";
dataToDisplay += "<p> Attributes: " + item.Used_By_Heroes + "</p>";
}
return dataToDisplay;
My code seems to know about itemGameResult.Items_Game.Items but not when I want to go further into .Items_Index.
I have the following classes:
public class DotaItemsGameResult
{
public DotaItemsGameResultProperties Items_Game { get; set; }
}
public class DotaItemsGameResultProperties
{
public List<DotaItemsGameRarities> Rarities { get; set; }
public List<DotaItemsGameItems> Items { get; set; }
}
public class DotaItemsGameItems
{
public List<DotaItemsGameItem> Item_Index { get; set; }
}
public class DotaItemsGameItem
{
public string Name { get; set; }
public string Hidden { get; set; }
public string Item_Class { get; set; }
public string Item_Name { get; set; }
public string Item_Slot { get; set; }
public string Item_Quality { get; set; }
public string Min_Ilevel { get; set; }
public string Max_Ilevel { get; set; }
public string Item_Description { get; set; }
public string Item_Type_Name { get; set; }
public List<DotaItemsGameUsedByHero> Used_By_Heroes { get; set; }
}
Basically, my aim is to be able to get at the Used_By_Heroes data in my loop but I can't.
In my for each, itemGameResult.Items_Game.Items is fine, but itemGameResult.Items_Game.Items.Item_Index is not and I can't see why.
I can't access the the Item_Index when I use dot notation, there's no Item_Index where I would expect there to be. If I put it in anyway and try to compile, I see this:
Error 1 'System.Collections.Generic.List' does not contain a definition for 'Item_Index' and no extension method 'Item_Index' accepting a first argument of type 'System.Collections.Generic.List' could be found (are you missing a using directive or an assembly reference?).
Any help would be fantastic.
Problem is that the Items property of the class DotaItemsGameResultProperties is a collection (List<DotaItemsGameItems>) so it doesn't have a property Item_Index. Not sure what do you want to achieve, but one possibility to fix this is to iterate on this collection also:
string dataToDisplay = "";
foreach (DotaItemsGameItems items in itemGameResult.Items_Game.Items)
{
foreach (DotaItemsGameItem item in items.Item_Index)
{
dataToDisplay += "<h3> Item: " + item.Name + "</h3>";
dataToDisplay += "<p> Quality: " + item.Item_Quality + "</p>";
dataToDisplay += "<p> Attributes: " + item.Used_By_Heroes + "</p>";
}
}
return dataToDisplay;
This is to illustrate the structure of your data, you can do this in a more concise way:
string dataToDisplay = "";
var allItems = itemGameResult.Items_Game.Items.SelectMany(i => i.Item_Index);
foreach (DotaItemsGameItem item in allItems)
{
dataToDisplay += "<h3> Item: " + item.Name + "</h3>";
dataToDisplay += "<p> Quality: " + item.Item_Quality + "</p>";
dataToDisplay += "<p> Attributes: " + item.Used_By_Heroes + "</p>";
}
return dataToDisplay;

The specified table does not exist[entity]

I have spent hours trying to figure out why my database cannot find the table I have found numerous examples and none have seemed to help. I have created a separate class to handle the database operations so I can use it on multiple pages.
Here is the code
[Table]
public class MatchItem
{
[Column(IsPrimaryKey = true, CanBeNull=false,IsDbGenerated=true)]
public int MatchID { get; set; }
[Column(CanBeNull = false)]
public string MatchNumber { get; set; }
[Column(CanBeNull = false)]
public string EventName { get; set; }
[Column(CanBeNull = false)]
public DateTime Time { get; set; }
[Column(CanBeNull = false)]
public string[] RedTeams { get; set; }
[Column(CanBeNull = false)]
public string[] BlueTeams { get; set; }
[Column(CanBeNull = false)]
public int RedFinal { get; set; }
[Column(CanBeNull = false)]
public int BlueFinal{ get; set; }
}
Here is the Data context
public class MatchDataContext:DataContext
{
public MatchDataContext(string connectionString) :
base(connectionString)
{
}
public Table<MatchItem> Matches
{
get
{
return this.GetTable<MatchItem>();
}
}
}
I made a class so I could use it on multiple pages
public class MatchDBManager
{
private static string connectionString = #"Data Source=isostore:/DB.sdf";
public MatchDBManager()
{
initialize();
}
public void initialize()
{
using (MatchDataContext Mchdb = new MatchDataContext(connectionString))
{
if (Mchdb.DatabaseExists())
{
Console.WriteLine("DB already exists");
}
else
{
Mchdb.CreateDatabase();
Console.WriteLine("DB created");
}
}
}
public void addMatchData(IList<MatchItem> data)
{
//this.clearData();
//initialize();
using (MatchDataContext Mchdb = new MatchDataContext(connectionString))
{
Mchdb.Matches.InsertAllOnSubmit(data);
Mchdb.SubmitChanges();
}
}
public IList<MatchItem> getTeamData(string teamNum)
{
IList<MatchItem> MatchList = null;
using (MatchDataContext Mchdb = new MatchDataContext(connectionString))
{
IQueryable<MatchItem> mchQuery = from mch in Mchdb.Matches where (mch.RedTeams[0] == teamNum || mch.RedTeams[1] == teamNum || mch.RedTeams[2] == teamNum || mch.BlueTeams[0] == teamNum || mch.BlueTeams[1] == teamNum || mch.BlueTeams[2] == teamNum) select mch;
MatchList = mchQuery.ToList();
}
return MatchList;
}
public IList<MatchItem> getEventData(string eventID)
{
IList<MatchItem> MatchList = null;
using (MatchDataContext Mchdb = new MatchDataContext(connectionString))
{
IQueryable<MatchItem> mchQuery = from mch in Mchdb.Matches where mch.Event == eventID select mch;
MatchList = mchQuery.ToList();
}
return MatchList;
}
private void clearData()
{
using (MatchDataContext Mchdb = new MatchDataContext(connectionString))
{
if (Mchdb.DatabaseExists())
{
Mchdb.DeleteDatabase();
}
}
}
}
I have the error The specified table does not exist[Match].
Added here is where I download
public IList<MatchItem> ParseXML(XmlReader reader)
{
//List<string> save = new List<string>();
List<MatchItem> MatchList= new List<MatchItem>();
XElement matchData;
matchData = XElement.Load(reader);
StringBuilder output = new StringBuilder();
int count = 0;
var matches = from item
in matchData.Elements("match")
select item;
foreach (XElement eachmatch in matches)
{
MatchItem mch = new MatchItem();
string Time = ((eachmatch.Element("pubdate").Value).ToString());
mch.EventName = ((eachmatch.Element("event").Value).ToString());
mch.MatchNumber = ((eachmatch.Element("mch").Value).ToString() + (eachmatch.Element("typ").Value).ToString());
string[] RT = { eachmatch.Element("red1").Value.ToString(), eachmatch.Element("red2").Value.ToString(), eachmatch.Element("red3").Value.ToString() };
string[] BT = { eachmatch.Element("blue1").Value.ToString(), eachmatch.Element("blue2").Value.ToString(), eachmatch.Element("blue3").Value.ToString() };
string RF = ((eachmatch.Element("rfin").Value).ToString());
string BF = ((eachmatch.Element("bfin").Value).ToString());
// Time = Time.Substring(0, (Time.IndexOf("+") - 1));
mch.Time = DateTime.Parse(Time);
mch.RedTeams = RT;
mch.BlueTeams = BT;
mch.RedFinal = int.Parse(RF);
mch.BlueFinal= int.Parse(BF);
mch.MatchID = count;
count += 1;
MatchList.Add(mch);
}
return MatchList;
}
This is where I call this method
void client_DownloadStringCompleted(object sender, DownloadStringCompletedEventArgs e)
{
initializeDB();
if (e.Error == null)
{
XmlReader reader = XmlReader.Create(new StringReader(e.Result));
DownloadInfo di = new DownloadInfo();
IList <MatchItem>data= di.ParseXML(reader);
outputer(data);
addData(data.ToList<MatchItem>());
}
else
{
IList<MatchItem> data = getTeamData(strMyTeam);
outputer(data);
}
}
I ended up removing the DatabaseManager class and putting the functions in the main code
Then I output them to the screen here
public void outputer(IList<MatchItem> mch)
{
for (int i = 0; i < mch.Count; i++)
{
Score sc = new Score();
sc.Width = lsbData.Width;
sc.Height = sc.Height;
sc.Time = mch[i].Time.ToString();
sc.Event = mch[i].EventName;
sc.RT = mch[i].RedTeams[0] + " " + mch[i].RedTeams[1] + " " + mch[i].RedTeams[2];
sc.BT = mch[i].BlueTeams[0] + " " + mch[i].BlueTeams[1] + " " + mch[i].BlueTeams[2];
sc.RF = mch[i].RedFinal.ToString();
sc.BF = mch[i].BlueFinal.ToString();
lsbData.Items.Add(sc);
}
}
*note:score is a custom control that works(and worked) before the database code *
I don't see where you actually create a Match Object.
if you have you need to include that code in the question as well. and if you haven't, that would explain why it doesn't exist.
Addition
in order to add Match Objects to a list you will have to create the objects first then add them to the list, I don't think you can create the whole list of objects before creating each individual object.
more Additional Information
the object still needs to be created before you can add items to it. that is what the error is telling you. you don't have the object to insert data into.
Match Table1 = new Match();
this creates a new Match object which allows you to access the pieces of the object and insert data into the object like this
Table1.MatchNumber = 42
you can't add to something to a memory location until you set aside that memory location for that specific person and give it a name.
when you create that class you can add functions and all sorts of fun stuff to it, but you can't use any of it until you have created a Match Object.
you can't add something to a list that doesn't exist, you have to create the Match Object first, then add it to the list

Categories

Resources