Retrieving hierarchy using ADOMD and not MDX query - c#

I want to retrieve hierarchy from one of the cube. I want to form a JSON structure so I am hoping if I can use ADOMD and use a recursive function to get this information and show the result in TreePanel.
I need to form JSON from the output.
foreach (var att in dimension.Hierarchies)
{
foreach (var m in att.Levels[1].GetMembers())
{
var path = att.UniqueName;
}
}
The above code only gets me level 1 attributes. I don't know how to get all the child attributes for given attribute.
Please help

To modify your original code to loop all the levels (instead of just level 1) is simple, but I'm guessing you are after the names of the members within each level.
Your original line var path = att.UniqueName; will return the same value many times over, won't it?
foreach (var att in dimension.Hierarchies)
{
foreach (var lev in att.Levels) //NEW LOOP
{
foreach (var m in lev.GetMembers())
{
var membername = m.UniqueName; //GET VALUE HERE
}
}
}
Where I have used UniqueName you could use any member property - read about ADOMD to find out what is available.

Related

C# The same item is keep adding to list using Foreach loop

I am trying to go through an xml document and per each node add some attribute values into a list using foreach loop. I am accessing the right part of xml document, but after each iteration of foreach loop, all the values are overwritten with new one. So in the end there is a List of all the same items.
IEnumerable<XElements> accesses = steps.Descendants("Access").Where(acc => acc.Attributes("Scope").First().Value == "GlobalVariable);
foreach (XElement access in accesses)
{
IEnumerable<XElement> accessComponent = access.Descendants("Component").ToList();
newGlobVar.DbName = accessComponent.First().Attribute("Name")?.Value;
newGlobVar.TagName = accessComponent.ElementAt(1).First().Attribute("Name")?.Value;
globalVariables.Add(newGlobVar);
}
return globalVariables;
You have only one instance of the newGlobVar variable and you change its properties.
That's why also properties of added items do change.
You have to create one new instance of the variable for each foreach loop.

C#: Why does my string return object type and not the value it contains?

I am looping through a List, and trying to instantiate one of the properties as a string, but it returns the type:
{Namespace.Collection}
If I put a break-point, I can see that it holds the value I need.
How can I make it return the value and not the type?
foreach (var PropertyName in ListName) {
string n = PropertyName.ToString();
}
UPDATE (added more of my code, as well as an attempt of implementing suggested solutions):
foreach (DataRow dr in ds.Tables[0].Rows) {
//PaidTrips is my ObservableCollection instance.
//PaidTrip is my holder class which it has been bound to.
PaidTrips.Add(new PaidTrip {
LicenseHolderID = dr[0].ToString(),
// adding more properties
});
List<PaidTrip> theseTrips = PaidTrips
.GroupBy(p => new { p.LicenseHolderID })
.Select(g => g.First())
.ToList();
foreach (PaidTrip PaidTrips in theseTrips) {
foreach (var LicenseHolderID in PaidTrips.GetType().GetProperties()) {
string n = LicenseHolderID.GetValue(PaidTrips).ToString();
// code to create PDF
}
gfx.DrawString(n, new XFont("Arial", 40, XFontStyle.Bold), ridelGreen, new XPoint(40, 350));
This is what I do with string n. But when the PDF is created, the string output is System.Action1[System.Action]`
What am I doing wrong?
You need to loop through the Property Types in your custom class, after looping through the list. First we need an additional loop - to loop through each ClassName Object in ListName list.
foreach (ClassName myObj in ListName)
{
foreach (var PropertyName in myObj.GetType().GetProperties())
{
string n = PropertyName.GetValue(myObj).ToString();
}
}
Then we need to loop the actual properties of the current loop ClassName object.
Then you pass the argument .GetValue (as you are now looping through the properties - the actual properties assigned, not the definition of properties).
After, you still need to specify what object you want the value of. So by passing myObj, you are specifying the ClassName->Property of the current loop of ListName.
EDIT:
List<Notes> myNotesNow = new List<Notes>();
myNotesNow.Add(new Notes
{
note1 = "Valuye"
// adding more properties
});
List<Notes> theseTrips = myNotesNow;
foreach (Notes PaidTrips in theseTrips)
{
foreach (var myVariable in PaidTrips.GetType().GetProperties())
{
string n = myVariable.GetValue(PaidTrips).ToString();
string forBreakPoint = "";
// code to create PDF
}
}
For your question - I guess that ListName is not of type string and so you get the expected behavior (see: https://learn.microsoft.com/en-us/dotnet/api/system.object.tostring?view=net-5.0#the-default-objecttostring-method)
In that case you can override the ToString() function of that object to return whatever you need like this:
public override string ToString()
{
return "whatever you want including class properties";
}
On another note, the general approach to variable naming in C# is camelCase and starts with lower case so I suggest to name your variables propertName instead of PropertyName and listName instead of ListName.
Moreover - naming variables for how they are implemented (ListName) is not a best practice as it binds them together, not allowing flexibility in case implementation changes (that comment is true only if it makes sense, as I dont see all the code)
Cheers

Access Attributes of object inside a dictionary

I am working on a winforms application using C#. I have a dictionary with specific objects, the object have attributes Id and DocType. How can i access the attributes of every object in a foreach statement. i Am trying with the following code but is not working. Any help pls?
foreach (var doc in crs.DocDictionary)
{
Console.WriteLine( doc.Id);
Console.WriteLine(doc.docType);
}
If you foreach on a dictionary you get a sequence of KeyValuePair<TKey,TValue>; try:
foreach (var doc in crs.DocDictionary.Values)
{
Console.WriteLine(doc.Id);
Console.WriteLine(doc.docType);
}
or:
foreach (var pair in crs.DocDictionary)
{
Console.WriteLine(pair.Key);
Console.WriteLine(pair.Value.Id);
Console.WriteLine(pair.Value.docType);
}

linq looping through tags with the same name

I'm some what new to linq could uses some help..
I have an xml file that looks like this:
<InputPath>
<path isRename="Off" isRouter="Off" pattern="pattern-1">d:\temp1</path>
<path isRename="Off" isRouter="pattern-1">d:\temp2</path>
</InputPath>
I need to loop through and get the key values of the tag "path".
What I have so far is
var results = from c in rootElement.Descendants("InputPath") select c;
foreach (XElement _path in results)
{
string value = _path.Element("path").Value;
}
But I only get the last <path> value. Any help would be great.
Have you tried just just enumerating the path items?
foreach (var element in rootElement.Descendants("path"))
{
var value = element.Value;
}
You'll only get the first element that way, because that's what the Element method gives you: the first child element with the given name.
If you want multiple elements you can just use Elements instead:
// Note: the query expression here is pointless.
var results = from c in rootElement.Descendants("InputPath") select c;
foreach (XElement _path in results)
{
string value = _path.Elements("path").Value;
// Use value here...
}
Alternatively, use the Elements extension method and do it all in one go:
foreach (var path in rootElement.Descendants("InputPath").Elements("path"))
{
string value = path.Value;
// Use value here
}
If that doesn't help, please give more information about what you're trying to do and what the problem is.
If by "last" you mean "the element contents" that's because you're using the Value property. If you want the attributes within the path element, you need the Attribute method, as shown by IamStalker, although personally I'd usually cast the XAttribute to string (or whatever) rather than using the Value property, in case the attribute is missing. (It depends on what you want the behaviour to be in that case.)
What you need is, to loop through the attributes like so
foreach (XElement xElem in rootElement.Descendants("InputPath"))
{
string isRename = xElem.Attribute("isRename").Value;
}

Extracting XElement children and grandchildren by name

I have an XElement (myParent) containing multiple levels of children that I wish to extract data from. The elements of interest are at known locations in the parent.
I understand that I am able to get a child element by:
myParent.Element(childName);
or
myParent.Element(level1).Element(childName);
I am having trouble figuring out how to do this if I want to loop through an array offor a list of elements that are at different levels, and looping through the list. For instance, I am interested in getting the following set of elements:
myParent.Element("FieldOutputs").Element("Capacity");
myParent.Element("EngOutputs").Element("Performance")
myParent.Element("EngOutputs").Element("Unit").Element("Efficiency")
How can I define these locations in an array so that I can simply loop through the array?
i.e.
string[] myStringArray = {"FieldOutputs.Capacity", "EngOutputs.Performance", "EngOutputs.Unit.Efficiency"};
for (int i=0; i< myArray.Count(); i++)
{
XElement myElement = myParent.Element(myStringArray);
}
I understand that the method above does not work, but just wanted to show effectively what I am trying to achieve.
Any feedback is appreciated.
Thank you,
Justin
While normally I'm reluctant to suggest using XPath, it's probably the most appropriate approach here, using XPathSelectElement:
string[] paths = { "FieldOutputs/Capacity", "EngOutputs/Performance",
"EngOutputs/Unit/Efficiency"};
foreach (string path in paths)
{
XElement element = parent.XPathSelectElement(path);
if (element != null)
{
// ...
}
}
The Descendants() method is what you're looking for, I believe. For example:
var descendants = myParent.Descendants();
foreach (var e in descendants) {
...
}
http://msdn.microsoft.com/en-us/library/system.xml.linq.xelement.descendants.aspx
Edit:
Looking at your question more closely, it looks like you may want to use XPathSelectElements()
var descendants = myParent.XPathSelectElements("./FieldOutputs/Capacity | ./EngOutputs/Performance | ./EngOutputs/Units/Efficency");
http://msdn.microsoft.com/en-us/library/bb351355.aspx

Categories

Resources