I have a LINQ Statement. It searches an XML file. (See example below) There are certain nodes that are required to have information in them. (Not empty) The LINQ Statement returns the transactions that have nodes which are empty, because these are required.
XML File Example:
<OnlineBanking>
<Transactions>
<Txn>
<UserName>John Smith</UserName>
<CustomerStreet>123 Main</CustomerStreet>
<CustomerStreet2></CustomerStreet2>
<CustomerCity>New York</CustomerCity>
<CustomerState>NY</CustomerState>
<CustomerZip>12345</CustomerZip>
</Txn>
</Transactions>
</OnlineBanking>
LINQ Statement:
//Start LINQ statement
var transactionList =
from transactions in root.Elements(XName.Get("Transactions")).Elements().AsEnumerable()
where transactions.Elements().Any
(
el =>
String.IsNullOrEmpty(el.Value) &&
elementsThatCannotBeEmpty.Contains(el.Name)
)
select transactions;
My Question:
I have the required fields (ie. CustomerStreet, CustomerCity, etc) in a database table. Below I have hard coded the XName's that are required. However, I want this to be dynamic from the database.
var elementsThatCannotBeEmpty = new HashSet<XName>
{
XName.Get("CustomerStreet"),
XName.Get("CustomerCity"),
XName.Get("CustomerState"),
XName.Get("CustomerZip")
};
Here is how I am retrieving the fields that are required from the database:
List<Setting> settingList = SettingsGateway.SelectBySettingType("VerifyField");
foreach (Setting SettingValue in settingList)
{
string strSettingType = setting.SettingType;
}
How do I take my database result loop and dynamically add XName.Get values?
Thank you so much for your help!
You're trying to check whether Any() of the strings in settingList are empty:
if (settingList.Any(
name => String.IsNullOrEmpty(el.Element(name).Value)
)
There is an implicit conversion from string to XName, so you don't actually need to call XName.Get.
If you want to, though, you could write el.Element(XName.Get(name))
Related
String priceID = codeArray[0];
var priceResult = from PRICE_LIST in priceContext.PRICE_LIST
where PRICE_LIST.PRICE_ID == priceID
select new
{
PRICE_LIST.RETAIL,
PRICE_LIST.WHOLESALE
}.ToList();
I'm receiving a compile error that the anonymous type does not contain a definition for ToList() and I'm not sure why? I've seen many examples where queries are stored using this method. I can do priceResult.ToList(), but both the retail and wholesale price columns are in the same list element. So I can't get retail by selecting the first element ect. New to EF & LINQ and still on the learning curve.
You need to put the entire LINQ within parentheses like this:
var priceResult = (from PRICE_LIST in priceContext.PRICE_LIST
where PRICE_LIST.PRICE_ID == priceID
select new
{
PRICE_LIST.RETAIL,
PRICE_LIST.WHOLESALE
}).ToList();
otherwise it tries to make each new object to a list
I am using Json.net
I have created a JArray and parsing the id values from it like so -
JArray userData = JArray.Parse(response.Content);
foreach (JObject content in userData.Children<JObject>())
{
items.Add(content["id"].ToString());
}
However I was trying to also do this usig Linq -
var items = userData.Where(x => x["id"].ToString() != null).ToList();
This seems to be a faster way to do this, however the problem I am having is that using the first method only adds the id values as I wanted, the Linq option puts the entire data set into items when the condition is met.
How an I change my condition so that it only extracts the id values?
It seems like you actually want LINQ Select.
It allows you to get items by projecting each element of a sequence into a new form.
var items = userData.Select(x => x["id"].ToString()).ToList();
i am reading a xml file and querying by LINQ this below way
XDocument document = XDocument.Load(xmlFilePath);
var query = document.Descendants("orders").Select(c => c);
query = query.OrderBy(sortColumn + " " + OrderDirection);
query = query.Skip(lowerPageBoundary - 1 * rowsPerPage).Take(rowsPerPage);
DataTable table = query.ToList().ConvertToDataTable();
table.Locale = System.Globalization.CultureInfo.InvariantCulture;
//adapter.Fill(table);
return table;
but getting error No property or field 'OrderID' exists in type 'XElement' (at index 0)
this is my sample xml which i am querying by LINQ
<?xml version="1.0" encoding="utf-8"?>
<Root>
<Orders>
<OrderID>10248</OrderID>
<CustomerID>VINET</CustomerID>
<EmployeeID>5</EmployeeID>
<OrderDate>1996-07-04T00:00:00</OrderDate>
<RequiredDate>1996-08-01T00:00:00</RequiredDate>
<ShippedDate>1996-07-16T00:00:00</ShippedDate>
<ShipVia>3</ShipVia>
<Freight>32.3800</Freight>
<ShipName>Vins et alcools Chevalier</ShipName>
<ShipAddress>59 rue de l'Abbaye</ShipAddress>
<ShipCity>Reims</ShipCity>
<ShipPostalCode>51100</ShipPostalCode>
<ShipCountry>France</ShipCountry>
</Orders>
</Root>
in debug mode i expand the result view and found order id exist. here is screen shot.
so tell me where i made the mistake in code. please guide. thanks
What are sortColumn and OrderDirection? By the usage it looks like they are strings, but OrderBy doesn't take a string unless you're using Dynamic LINQ.
LINQ to XML doesn't give you properties for Elements. If you have an XElement e, you wouldn't be able to call e.OrderID. You must use the Element method like this e.Element("OrderID").Value. To plug that into the OrderBy method, you could do this:
query = query.OrderBy(e => e.Element("OrderID").Value);
As the comment points out, adding .Select(c => c) doesn't do anything. Also, you could chain the remaining methods like this:
var query = document.Descendants("orders")
.OrderBy(e => e.Element("OrderID").Value)
.Skip(lowerPageBoundary - 1 * rowsPerPage)
.Take(rowsPerPage);
With Dynamic LINQ, you'll still need to use the Element method. Dynamic Linq to Xml example suggests that it should be something like this, but I haven't tested it:
var query = document.Descendants("orders")
.OrderBy(String.Format("Element(\"{0}\").Value {1}", sortColumn, OrderDirection))
.Skip(lowerPageBoundary - 1 * rowsPerPage)
.Take(rowsPerPage);
It should be possible without using Dynamic LINQ since you have to use the Element method and pass in the name of the column you're sorting by anyway. You'd just need to branch and use OrderByDescending when OrderDirection is "descending."
In my database field I have a Positions field, which contains a space separated list of position codes. I need to add criteria to my query that checks if any of the locally specified position codes match at least one of the position codes in the field.
For example, I have a local list that contains "RB" and "LB". I want a record that has a Positions value of OL LB to be found, as well as records with a position value of RB OT but not records with a position value of OT OL.
With AND clauses I can do this easily via
foreach (var str in localPositionList)
query = query.Where(x => x.Position.Contains(str);
However, I need this to be chained together as or clauses. If I wasn't dealing with Linq-to-sql (all normal collections) I could do this with
query = query.Where(x => x.Positions.Split(' ').Any(y => localPositionList.contains(y)));
However, this does not work with Linq-to-sql as an exception occurs due it not being able to translate split into SQL.
Is there any way to accomplish this?
I am trying to resist splitting this data out of this table and into other tables, as the sole purpose of this table is to give an optimized "cache" of data that requires the minimum amount of tables in order to get search results (eventually we will be moving this part to Solr, but that's not feasible at the moment due to the schedule).
I was able to get a test version working by using separate queries and running a Union on the result. My code is rough, since I was just hacking, but here it is...
List<string> db = new List<string>() {
"RB OL",
"OT LB",
"OT OL"
};
List<string> tests = new List<string> {
"RB", "LB", "OT"
};
IEnumerable<string> result = db.Where(d => d.Contains("RB"));
for (int i = 1; i < tests.Count(); i++) {
string val = tests[i];
result = result.Union(db.Where(d => d.Contains(val)));
}
result.ToList().ForEach(r => Console.WriteLine(r));
Console.ReadLine();
Basically I have a single element inside of an xml file where I store settings for my application. This element mirrors a class that I have built. What I'm trying to do using LINQ, is select that single element, and then store the values stored inside of that element into an instance of my class in a single statement.
Right now I'm selecting the element seperately and then storing the values from that element into the different properties. Of course this turns into about six seperate statements. Is it possible to do this in a single statement?
It will be better if you can show your XML but you can get general idea from code below
XDocument doc = //load xml document here
var instance = from item in doc.Descendants("ElementName")
select new YourClass()
{
//fill the properties using item
};
You can use LINQ to XML, e.g.
var document = XDocument.Load("myxml.xml");
document.Element("rootElement").Element("myElement").Select(e =>
new MySettingsClass
{
MyProperty = e.Attribute("myattribute").Value,
MyOtherProperty = e.Attribute("myotherattribute").Value
});
See http://msdn.microsoft.com/en-us/library/bb387098.aspx for more details.