I need your help in getting parent-child URL list from full URL, maybe using recursively.
For example, below is URL in flat structure. I have to parse in parent-child form with inner level of child structure.
https://domain/UrlA/UrlA_L1/UrlA_L1_L2
https://domain/UrlA/UrlA_L1/UrlA2_L1_L2
https://domain/UrlB/UrlB_L1/UrlB_L1_L2
https://domain/UrlC/UrlC_L1/UrlC_L1_L2
https://domain/UrlD/UrlD_L1/UrlD_L1_L2/UrlD_L1_L2_L3
https://domain/UrlE/UrlE_L1/UrlE_L1_L2/UrlE_L1_L2_L3
https://domain/UrlF/UrlF_L1/UrlF_L1_L2/UrlF_L1_L2_L3
into a list of URL with child-parent relationship.
public class HtmlSiteMap
{
public string Url { get; set; }
public string PageTitle { get; set; }
public int UrlLevel { get; set; }
public List<HtmlSiteMap> Childrens { get; set; }
}
my expected output
{
Url: https://domain/UrlA,
PageTitle : UrlA,
UrlLevel : 0 ,
Childrens : {
Url : https://domain/UrlA/UrlA_L1,
PageTitle : UrlA_L1,
UrlLevel : 1,
Childrens : {
Url : https://domain/UrlA/UrlA_L1/UrlA_L1_L2,
PageTitle : UrlA_L1_L2,
UrlLevel : 2,
Childrens : null
},
{
Url : https://domain/UrlA/UrlA_L1/UrlA2_L1_L2,
PageTitle : UrlA2_L1_L2,
UrlLevel : 2,
Childrens : null
}
},
Url: https://domain/UrlB,
PageTitle : UrlB,
UrlLevel : 0 ,
Childrens : {
Url : https://domain/UrlB/UrlB_L1,
PageTitle : UrlB_L1,
UrlLevel : 1,
Childrens : {
Url : https://domain/UrlB/UrlB_L1/UrlB_L1_L2,
PageTitle : UrlB_L1_L2,
UrlLevel : 2,
Childrens : null
}
}
.................
.................
..................
}
I have tried to achieve by splitting and recursively. But unable to get a result. Your help will be appreciated.
Here is another reverse solution. I am working on preordered list, constructing nodes from roots to leaves. This code looks more readable and understandable by beginners in recursion.
static void Main(string[] args)
{
var input = new[]
{
new Uri("https://domain/UrlA/UrlA_L1/UrlA_L1_L2"),
new Uri("https://domain/UrlA/UrlA_L1/UrlA2_L1_L2"),
new Uri("https://domain/UrlB/UrlB_L1/UrlB_L1_L2"),
new Uri("https://domain/UrlC/UrlC_L1/UrlC_L1_L2"),
new Uri("https://domain/UrlD/UrlD_L1/UrlD_L1_L2/UrlD_L1_L2_L3"),
new Uri("https://domain/UrlE/UrlE_L1/UrlE_L1_L2/UrlE_L1_L2_L3"),
new Uri("https://domain/UrlF/UrlF_L1/UrlF_L1_L2/UrlF_L1_L2_L3")
};
var rows = input.Select(u => u.AbsolutePath.Substring(1))
.OrderBy(s => s).Select(s => s.Split('/')).ToList();
var rootNodes = new List<HtmlSiteMap>();
ProcessNodes(rootNodes, rows,
input.Select(u => $"{u.Scheme}://{u.Host}/").Distinct().FirstOrDefault(), 0);
foreach (var node in rootNodes)
Console.WriteLine(node.ToString());
}
static void ProcessNodes(List<HtmlSiteMap> children, List<string[]> rows, string prefix, int level)
{
if (rows.Count == 0)
return;
HtmlSiteMap currentNode = null;
var subRows = new List<string[]>();
foreach (var parts in rows)
{
if (parts.Length == 0)
continue;
subRows.Add(parts.Skip(1).ToArray());
if (currentNode != null && currentNode.PageTitle == parts[0])
continue;
if(currentNode != null)
ProcessNodes(currentNode.Children, subRows, prefix + currentNode.PageTitle + "/", level + 1);
currentNode = new HtmlSiteMap
{
Url = prefix + parts[0],
PageTitle = parts[0],
UrlLevel = level
};
children.Add(currentNode);
subRows.Clear();
}
if(currentNode != null && subRows.Count > 0)
ProcessNodes(currentNode.Children, subRows, prefix + currentNode.PageTitle + "/", level + 1);
}
public class HtmlSiteMap
{
public string Url { get; set; }
public string PageTitle { get; set; }
public int UrlLevel { get; set; }
//Also renamed this from Childrens to Children
public List<HtmlSiteMap> Children { get; set; }
public HtmlSiteMap()
{
Children = new List<HtmlSiteMap>();
}
//Borrowed this from previous answer
public override string ToString()
{
var shift = new string(' ', UrlLevel);
var sb = new StringBuilder();
sb.AppendLine(shift + $"Url: {Url},");
sb.AppendLine(shift + $"PageTitle: {PageTitle},");
sb.AppendLine(shift + $"UrlLevel: {UrlLevel},");
sb.AppendLine(shift + "Children:");
if (Children.Count == 0)
{
sb.AppendLine(shift + "-");
}
else
{
foreach (var child in Children)
{
sb.AppendLine(child.ToString());
}
}
return sb.ToString();
}
}
A base version (without errors handling) may look like this:
static void Main(string[] args)
{
var input = new List<string>
{
"https://domain/UrlA/",
"https://domain/UrlA/UrlA_L1/",
"https://domain/UrlA/UrlA_L1/UrlA_L1_L2",
"https://domain/UrlA/UrlA_L1/UrlA2_L1_L2",
"https://domain/UrlB",
"https://domain/UrlB/UrlB_L1",
"https://domain/UrlB/UrlB_L1/UrlB_L1_L2",
"https://domain/UrlC/UrlC_L1/UrlC_L1_L2",
"https://domain/UrlD/UrlD_L1/UrlD_L1_L2/UrlD_L1_L2_L3",
"https://domain/UrlE/UrlE_L1/UrlE_L1_L2/UrlE_L1_L2_L3",
"https://domain/UrlF/UrlF_L1/UrlF_L1_L2/UrlF_L1_L2_L3"
};
var output = new List<HtmlSiteMap>();
foreach (var url in input)
{
var parts = url.Split(#"/", StringSplitOptions.RemoveEmptyEntries);
var current = new HtmlSiteMap
{
Url = url,
PageTitle = parts[^1]
};
var parentName = parts[^2];
static HtmlSiteMap FindParent(List<HtmlSiteMap> score, string name)
{
foreach (var item in score)
{
if (item.PageTitle == name)
{
return item;
}
var inChild = FindParent(item.Childrens, name);
if (inChild != null)
{
return inChild;
}
}
return null;
}
var parent = FindParent(output, parentName);
if (parent == null)
{
current.UrlLevel = 1;
output.Add(current);
}
else
{
current.UrlLevel = parent.UrlLevel + 1;
parent.Childrens.Add(current);
}
}
foreach (var current in output)
{
Console.WriteLine(current.ToString());
}
Console.ReadLine();
}
public class HtmlSiteMap
{
public string Url { get; set; }
public string PageTitle { get; set; }
public int UrlLevel { get; set; }
public List<HtmlSiteMap> Children { get; set; }
public HtmlSiteMap()
{
Children = new List<HtmlSiteMap>();
}
public override string ToString()
{
var shift = new string(' ', UrlLevel);
var sb = new StringBuilder();
sb.AppendLine(shift + $"Url: {Url},");
sb.AppendLine(shift + $"PageTitle: {PageTitle},");
sb.AppendLine(shift + $"UrlLevel: {UrlLevel},");
sb.AppendLine(shift + "Children:");
if (Children.Count == 0)
{
sb.AppendLine(shift + "-");
}
else
{
foreach (var child in Children)
{
sb.AppendLine(child.ToString());
}
}
return sb.ToString();
}
}
Related
I have this class, a hierarchy of categories.
class Categories
{
public long Id { get; set; }
public long ParentId { get; set; }
public string Name { get; set; }
public bool IsActive { get; set; }
public List<Categories> ChildrenData { get; set; }
}
How can I recursively iterate through this class of unknown depth and return the path to get there?
All "Id" values are unique. Say I want to find Id = 23 and get the path to get there by concatenating "Name".
For example, in the image below searching for ID = 23 would return: Default Category/Books/Nonfiction/Best-sellers
Example Hierarchy
My suggestion is that you first build an index:
public static Dictionary<long, Category> IndexBuilder(Category c)
{
var index = new Dictionary<long, Category>();
IndexBuilder(c, index);
return index;
}
private static void IndexBuilder(Category c, Dictionary<long, Category> index)
{
if (index.ContainsKey(c.Id))
return;
index[c.Id] = c;
foreach(var child in c.ChildrenData)
IndexBuilder(child, index);
}
Now you have a lookup, and your path is then easy to produce:
static IEnumerable<Category> PathToRoot(long id, Dictionary<long, Category> index)
{
// Presumably the parent id of the top category is a sentinel.
long current = id
while (current != 0)
{
var category = index[current];
yield return category;
current = category.ParentId;
}
}
Or maybe we just go until we run out of index:
static IEnumerable<Category> PathToRoot(long id, Dictionary<long, Category> index)
{
long current = id
while (index.ContainsKey(current))
{
var category = index[current];
yield return category;
current = category.ParentId;
}
}
Now you have a tool you can use to make your string:
static string Slash<T>(this IEnumerable<T> items) =>
string.Join("/", items);
var s = PathToRoot(23, index)
.Reverse()
.Select(c => c.Name)
.Slash();
See what I am doing here? Make a bunch of helper methods each of which is about five lines long, that can be composed together to make powerful solutions.
I have provided 2 ways, the first way is recursive and the last is not.
Recursive way, add a reference to your parent. This way when you find a match you can easily traverse your way back up the chain to create your path.
class Categories
{
public Categories Parent { get; set; }
public long Id { get; set; }
public long ParentId { get; set; }
public string Name { get; set; }
public bool IsActive { get; set; }
public List<Categories> ChildrenData { get; set; }
}
Then add a Find() method:
public string Find(long id)
{
if( Id == id )
{
return GetPath(); //<-- we need to code this next.
}
else
{
foreach( var entry in Categories)
{
string path = entry.Find(id);
if( path != null )
{
return path;
}
}
return null;
}
}
And finally the GetPath(), the assumption here is that the highest level instances of Categories do not have a Parent:
public string GetPath()
{
System.Text.StringBuilder sb = new StringBuilder();
Categories current = this;
while( current != null)
{
sb.Insert(0,current.Name);
if( current != this)
{
sb.Insert(0,"/");
}
current = Parent;
}
return sb.ToString();
}
Now if recursion isn't what you want, then pass in the current path to the Find() method.
public string Find(long id, string pathSoFar)
{
if (pathSoFar == null)
{
pathSoFar = Name;
}
else
{
pathSoFar = pathSoFar + Name;
}
if ( Id == id)
{
return pathSoFar;
}
else
{
foreach( var entry in Categories)
{
string path = entry.Find(id, pathSoFar + "/");
if( path != null )
{
return path;
}
}
return null;
}
}
Usage:
var nonRecusive = cats.Find(23, null);
This will get what you are looking for using recursion:
void Main()
{
var data = GetData();
Console.WriteLine(GetPath(data, 23, ""));
}
public String GetPath(Categories c, Int32 id, String path)
{
if (c.Id == id)
{
return path + "/" + c.Name;
}
foreach (var cd in c.ChildrenData)
{
var p = GetPath(cd, id, path + "/" + c.Name);
if (!String.IsNullOrWhiteSpace(p))
{
return p;
}
}
return "";
}
public class Categories
{
public long Id { get; set; }
public long ParentId { get; set; }
public string Name { get; set; }
public bool IsActive { get; set; }
public List<Categories> ChildrenData { get; set; }
}
public Categories GetData()
{
return
new Categories
{
Id = 1,
Name = "Default Category",
ChildrenData = new List<Categories>
{
new Categories
{
Id = 2,
Name = "Magazines",
ChildrenData = new List<Categories> {}
},
new Categories
{
Id = 2,
Name = "Books",
ChildrenData = new List<Categories>
{
new Categories
{
Id = 20,
Name = "Fiction",
ChildrenData = new List<Categories> {}
},
new Categories
{
Id = 21,
Name = "Nonfiction",
ChildrenData = new List<Categories>
{
new Categories
{
Id = 22,
Name = "New",
ChildrenData = new List<Categories> {}
},
new Categories
{
Id = 23,
Name = "Best-Sellers",
ChildrenData = new List<Categories> {}
},
}
}
}
}
}
};
}
So I've been bashing my head against a wall for a while on this one. What Im attempting to do is follow through a category trace defined as "category>child category> child of child category..." but for some reason, of which I am clearly failing to grasp, The categories that should have a parent sometimes fail to set their ParentId, not all the time though!?
string catString = "Category1Name>Category2Name>Category3Name";
if (!string.IsNullOrEmpty(catString)) {
string[] catStrings = catString.Split('>');
ProductCategory[] categories = new ProductCategory[catStrings.Length];
for (int j = 0; j < catStrings.Length; j++) {
string categoryName = catStrings[j];
ProductCategory parent = j > 0 ? categories[j - 1] : null;
if (j > 0) {
categories[j] = _context.ProductCategories.SingleOrDefault(x => x.Name.ToUpper().Replace(" ", "") == categoryName.ToUpper().Replace(" ", "") && x.ParentId == parent.Id);
} else {
categories[j] = _context.ProductCategories.SingleOrDefault(x => x.Name.ToUpper().Replace(" ", "") == categoryName.ToUpper().Replace(" ", ""));
}
if (categories[j] == null) {
if (j > 0) {
categories[j] = new ProductCategory { Name = categoryName, ParentId = parent.Id };
if (parent.Children == null) {
parent.Children = new List<ProductCategory>();
}
parent.Children.Add(categories[j]);
} else {
categories[j] = new ProductCategory { Name = categoryName };
}
_context.ProductCategories.Add(categories[j]);
categoriesCreated++;
}
}
product.Category = categories.Last();
}
A Category is defined as such
public int Id { get; set; }
public string Name { get; set; }
public int ParentId { get; set; }
public virtual List<ProductCategory> Children { get; set; }
String Examples
Glassware>Shot Glasses
Glassware>Wine Glasses
Glassware>Glass Carafes/Decanters/Jugs>Glass Carafes
Glassware>Glass Carafes/Decanters/Jugs>Glass Jugs
Tableware>Cutlery>Premium 18/10
Something simple like this works, using a TreeNode object to contain everything.
public class SO50846156
{
public TreeNode Test(String[] data)
{
var root = new TreeNode();
foreach (var line in data)
{
var split = line.Split('>');
var count = split.Length;
var item = root.Nodes.Add(split[0]);
if (1 < count)
{
var subCat = item.Nodes.Add(split[1]);
if (2 < count)
{
var catName = subCat.Nodes.Add(split[2]);
}
}
}
return root;
}
}
The root element gets created every time, and you get a node for each line of your data.
I'm not sure what yours is trying to accomplish that is different, but maybe this gives you some ideas.
i want to write a C# function which returns "alamaba" when i pass "Montgomery".
2nd example: Sitka --> Alaska
here is the list of the example:
List<PopulationUSA> result = new List<PopulationUSA>();
PopulationUSA usa = new PopulationUSA("Population in USA", 316128839, new List<PopulationUSA>());
result.Add(usa);
PopulationUSA alabama = new PopulationUSA("Alabama", 4833722, new List<PopulationUSA>());
usa.Items.Add(alabama);
alabama.Items.Add(new PopulationUSA("Birmingham", 212113, null));
alabama.Items.Add(new PopulationUSA("Montgomery", 201332, null));
alabama.Items.Add(new PopulationUSA("Mobile", 194899, null));
PopulationUSA alaska = new PopulationUSA("Alaska", 735132, new List<PopulationUSA>());
usa.Items.Add(alaska);
alaska.Items.Add(new PopulationUSA("Juneau", 32660, null));
alaska.Items.Add(new PopulationUSA("Ketchikan", 8214, null));
alaska.Items.Add(new PopulationUSA("Sitka", 9020, null));
here is the class:
public class PopulationUSA
{
public PopulationUSA(string name, int value, List<PopulationUSA> items)
{
Name = name;
Value = value;
Items = items;
}
public string Name { get; set; }
public int Value { get; set; }
public List<PopulationUSA> Items { get; set; }
}
How can i do that?
Thanks
you can add this method to the PopulationUSA class
public string FindParentsOfGrandChildren(string _name)
{
List<PopulationUSA> parents = Items.Where(s => s.Items.Any(c => c.Name == _name)).ToList();
if (parents != null)
{
string listparents = string.Empty;
for (int i = 0; i < parents.Count; i++)
{
if (i == 0)
{
listparents += parents[i].Name;
}
else
{
listparents += ", " + parents[i].Name;
}
}
return listparents;
}
else
{
return "Not found";
}
}
then use it like this in your example:
string WhereDoIBelong = usa.FindParentsOfGrandChildren("Montgomery")
it would be much better as a recursive method, finding parents of any type (not just "grandchildren") but that is your work!
I have this object:
public class dtHeader
{
public dtHeader ParentHeader { get; set; }
public string HeaderText { get; set; }
public string DataField { get; set; }
public bool Visible { get; set; }
public int DisplayOrder { get; set; }
}
I want to calculate using a lambda expression, the depth of the object, how many layers of the object in itself exists?
I saw this JavaScript post, but I am struggling to translate it to a one line lambda statement.
Lets say the object is as this new dtHeader(){ ParentHeader = null, HeaderText = "col1" };
the result would be 1
and for new dtHeader(){ ParentHeader = new dtHeader(){ ParentHeader = null, HeaderText = "col1" }, HeaderText = "col1" }; the result would be 2
I want to achieve this with a list<dtHeader>, so some of them would have a depth of 1 and others with deeper depths, and want the deepest depth.
_______ITEM_IN_LIST_OBJECT__
______1___2___3___4___5___6_
D 1. |_o_|_o_|_o_|_o_|_o_|_o_|
E 2. |_o_|___|_o_|___|_o_|_o_|
P 3. |___|___|_o_|___|_o_|___|
T 4. |___|___|___|___|_o_|___|
H 5. |___|___|___|___|_o_|___|
It must go infinitly(Until where it allows for objects to heap up inside eachother) deep.
var HeaderLayerCount = lDtCol.Where(n => n.ParentHeader != null)
.Where(n => n.ParentHeader.ParentHeader != null)
.Where(n => n.ParentHeader.ParentHeader.ParentHeader != null);
EDIT:
I just want to add that if you want to work on a specific depth level, for instance, all objects on a depth of 3, you can use this extra recursion function in the class
public class dtCol
{
public dtCol ParentHeader { get; set; }
public string HeaderText { get; set; }
public string DataField { get; set; }
public bool Visible { get; set; }
public int DisplayOrder { get; set; }
public int Depth { get { return ParentHeader != null ? ParentHeader.Depth + 1 : 1; } }
public int CurrentDepth { get; set; } //Set on initialisation
public dtCol getParent(dtCol col, int getDepth) //Gets the parent on a specific level after the first base level (1) else returns the previous not null child
{
return (col.ParentHeader != null && col.ParentHeader.CurrentDepth == getDepth) ? col.ParentHeader : this.getParent(col.ParentHeader, getDepth);
}
}
You can use it like so:
var HeaderLayerCount = lDtCol.OrderByDescending(n => n.Depth).First().Depth;
for (int hlc = 1; hlc <= HeaderLayerCount; hlc++)
{
var headerrow = new List<dtCol>();
//This foreach adds the parent header if not null else adds the not null child
lDtCol.ForEach(n =>
{
var h = n.getParent(n, hlc); //Get Parent, null is returned if parent does not exists
headerrow.Add((h != null) ? h : n); //If parent is null, add base dtCol so that the headers can be merged upwards.
});
//Do what you need with your new single dimensional list of objects
}
Why not implementing a int GetDepth() method on your class, that will reach the top most ancestor, counting each level?
Your query would then be much simpler.
I was outrunned by Frode, kudos to him
I had the same implementation:
public int GetDepth()
{
if (ParentHeader == null)
{
return 1;
}
else return 1 + ParentHeader.GetDepth();
}
using System;
using System.Linq;
namespace ConsoleApplication3
{
public class dtHeader
{
public dtHeader ParentHeader { get; set; }
public string HeaderText { get; set; }
public string DataField { get; set; }
public bool Visible { get; set; }
public int DisplayOrder { get; set; }
public int Depth
{
get
{
// If header has parent, then this depth is parent.depth + 1
if (ParentHeader != null)
return ParentHeader.Depth+1;
else
return 1; // No parent, root is depth 1
}
}
}
class Program
{
static void Main(string[] args)
{
dtHeader[] headers = {
new dtHeader { HeaderText = "dt1" },
new dtHeader { HeaderText = "dt2" },
new dtHeader { HeaderText = "dt3" },
new dtHeader { HeaderText = "dt4" },
new dtHeader { HeaderText = "dt5" }
};
headers[1].ParentHeader = headers[0];
headers[2].ParentHeader = headers[1];
headers[3].ParentHeader = headers[2];
headers[4].ParentHeader = headers[3];
var deepest = headers.OrderByDescending(item=>item.Depth).First();
Console.WriteLine(deepest.Depth+ ", " + deepest.HeaderText);
var runner = deepest;
while (runner.ParentHeader != null)
runner = runner.ParentHeader;
Console.WriteLine("The deepest root header is:" + runner.HeaderText);
}
}
}
Here's a lambda expression to get what you want:
Func<dtHeader, int> getDepth = null;
getDepth = dth =>
{
var depth = 1;
if (dth.ParentHeader != null)
{
depth += getDepth(dth.ParentHeader);
}
return depth;
};
You have to define it in two parts (assigning null & assigning the body) to let recursion work.
I modified Enigmativity's answer to make it work correctly:
Func<dtHeader, int, int> getDepth = null;
getDepth = (dth, depth) =>
{
if (dth.ParentHeader != null)
{
depth = getDepth(dth.ParentHeader, ++depth);
}
return depth;
};
Call it like this:
int depth = getDepth(header, 0)
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