Here is what I want to do:
string parseCode = from x in xml.Descendants("LogType")
where x.Attribute("ID").Value == string)ddlHistoryLogDefinitions.SelectedValue
select x.Attribute("ParseCode").Value;
But that gives error: "Cannot implicitly convert type 'System.Collections.Generic.IEnumerable' to 'string'"
There will only be one value for x.Attribute("ParseCode") but it insists on returning type IEnumerable<string>. How can I extract that value into a string ?
EDIT: Thank you for your responses. Here is what worked for me:
string parseCode = (from x in xml.Descendants("LogType")
where x.Attribute("ID").Value == (string) ddlHistoryLogDefinitions.SelectedValue
select (string) x.Attribute("ParseCode").Value).FirstOrDefault();
This trick was wrapping the entire linq query in () before the .FirstOrDefault().
Use .Single to select the only result if you know there will be one and only one:
string parseCode = (from x in xml.Descendants("LogType")
where x.Attribute("ID").Value == string)ddlHistoryLogDefinitions.SelectedValue
select x.Attribute("ParseCode").Value).Single();
Use .SingleOrDefault or .First If there might be none or more then one respectively.
You query returns a collection. If you need the first found LogType node, then you can do something like this:
string parseCode = xml.Descendants("LogType")
.Where(x => x.Attribute("ID").Value == (string)ddlHistoryLogDefinitions.SelectedValue)
.Select(arg => x.Attribute("ParseCode").Value)
.FirstOrDefault();
Will return null if no element found.
Related
I'm trying to select from CRM entity with "contains" key.
I tryed this:
var results = crm.new_supplycontractSet
.Where(x => x.new_city != null &&
x.new_city.Name.Contains("myChars"))
.ToList();
but it give me this error:
Invalid 'where' condition. An entity member is invoking an invalid property or method.
and this:
var result = (
from c in crm.new_supplycontractSet
from a in crm.new_comuneSet
where a.new_name.Contains(comune)
where c.new_city.Id == a.Id
select c)
.ToList();
But i can't figure out how to do it. The second try gives me this error:
A 'SelectMany' operation must be preceeded by a 'Where' operation that filters by an entity ID.
How can I select by a contains filter? "x.new_city" is an entity ref from crm.new_comuneSet.
PS:
I've just read something about the inaccessibility of the "entity.entityRef.Name.Contains()" because the "Name" property is not ground level and so it's not available for the ".contains" check.
At the end i got it. instead of contains clause, I had to install SqlClient and use the following:
results = (from x in crm.new_supplycontractSet
where x.new_city != null
where x.new_address != null
where SqlMethods.Like(x.new_city.Name, "city")
where SqlMethods.Like(x.new_address.Name, "street")
select ....).ToList();
hope this will help someone else :)
you can try converting your field and your filter to lower or upper case.
var results = crm.new_supplycontractSet
.Where(x => x.new_city != null &&
x.new_city.Name.ToLower().Contains(("myChars").ToLower()))
.ToList();
I think is better if you use StartsWith instead (and if is possible).
My entity NewsItem has a nullable foreign key property: LibraryID of type int?.
My issue is when I query the property and compare it with any value except null, I get exceptions.
Initially my code was:
int? lid = ...
var results = context.NewsItems
.Where(n => n.LibraryID == lid);
but it gives me no results at all, no matter what lid is.
So, I tried:
var results = context.NewsItems
.Where(n => n.LibraryID.Equals(lid));
gives exception:
Unable to create a constant value of type 'System.Object'. Only primitive types or enumeration types are supported in this context.
and then I tried:
var results = context.NewsItems
.Where(n => lid.Equals(n.LibraryID));
and got:
Unable to cast the type 'System.Nullable`1' to type 'System.Object'. LINQ to Entities only supports casting EDM primitive or enumeration types.
and this:
var results = context.NewsItems
.Where(n => object.Equals(lid, n.LibraryID));
gives same exception as the last one.
Now I was desperate, so I tried to complicate stuff (like other forums suggested, for example here):
var results = context.NewsItems
.Where(n => (lid == null ? n.LibraryID == null : n.LibraryID == lid));
but still getting same exception.
So... any SIMPLE workarounds?
How about
var results = context.NewsItems
.Where(n => lid.HasValue ? lid.Value == n.LibraryId.Value : (!n.LibraryId.HasValue) );
Hmm, that first snippet should work. I've used nullables like that many times. First thing I'd do is a sanity check just to make sure LibraryID is really int? and not long? or similar.
Other than that, you can try this:
var results = context.NewsItems
.Where(n => (lid.HasValue ? n.LibraryID == lid.Value : !n.LibraryID.HasValue));
Or to avoid the ?: within the query:
var results = lid.HasValue
? context.NewsItems.Where(n => n.LibraryID == lid.Value)
: context.NewsItems.Where(n => !n.LibraryID.HasValue);
It seems that EF does not find the correct operator overload. Therefore it produces wrong results if you set lid = null.
Use linq to objects by adding AsEnumerable() to your query and everything is fine:
var results = context.NewsItems.AsEnumeryble().Where(n => n.LibraryID == lid);
According to the MSDN docs (which I finally found), .Where() will only filter your collection. If you want to see if there are actually results, resolve by lazily executing the filtered query with .ToList(), GetEnumerator, or enumerating the collection with foreach;
This method is implemented by using deferred execution. The immediate
return value is an object that stores all the information that is
required to perform the action. The query represented by this method
is not executed until the object is enumerated either by calling its
GetEnumerator method directly or by using foreach in Visual C# or For
Each in Visual Basic.
http://msdn.microsoft.com/en-us/library/bb534803.aspx
int? lid = ...
var results = context.NewsItems
.Where(n => n.LibraryID == lid).ToList();
var results = context.NewsItems
.Where(n => n.LibraryID.HasValue && n.LibraryID.Value == lid.Value );
edit:
Previous filter was based on my understanding that you wanted to filter to entires having a particular value. Updated will filter to null or value.
var results = context.NewsItems
.Where(n => !n.LibraryID.HasValue || n.LibraryID.Value == lid.Value );
Considering the following code
IEnumerable<String> query = null;
query = from x in xml.Descendants(xmlMasterContainerName).Descendants(xmlElementName)
let guid = x.Attribute("guid") ?? new XAttribute("guid", "-1")
where x.Attribute(xmlAttributeIdName).Value == xmlAttributeIdValue
select guid.Value;
I get the 'object reference not set' when trying query.ToList()
This is very probably caused by 'select guid.Value' when 'x.Attribute(xmlAttributeIdName).Value == xmlAttributeIdValue' does not exist.
How can I check the where statement for existing value before selecting?
Thanks
In XLinq, you usually don't use Attribute().Value directly, because of the exact error you are getting. Instead, you cast it. The cast will result in null if Attribute() returned null, so there will be no exception.
So, you would change your where clause to this:
where ((string)x.Attribute(xmlAttributeIdName)) == xmlAttributeIdValue
and your select to this:
select (string)guid
BTW: I would write that code like this:
var query = xml.Descendants(xmlMasterContainerName)
.Descendants(xmlElementName)
.Where(x => ((string)x.Attribute(xmlAttributeIdName)) ==
xmlAttributeIdValue)
.Select(x => (string)x.Attribute("guid") ?? "-1");
If there is no attribute xmlAttributeIdName you will get an exception accessing Value property. Use casting instead (it will return default value). Also you don't need to create attribute - you can simply return value:
IEnumerable<String> query = null;
query = from x in xml.Descendants(xmlMasterContainerName)
.Descendants(xmlElementName)
where (string)x.Attribute(xmlAttributeIdName) == xmlAttributeIdValue
select (string)x.Attribute("guid") ?? "-1";
I am new to .net. I have a form in which there are two comboboxes cbProduct and cbBrandName and also a label lblPrice.
I am trying to implement the below code but it is showing blue scribbles to &&.
(Error: operator '&&' cannot be applied to operands of type 'lambda expression' and 'lambda expression')
I tried the below code: (not working)
lblPrice.Text = string.Empty;
lblPrice.Text = doc.Descendants("items"
).Where((x => x.Element("productname"
).Value.Equals(cbProduct.SelectedItem.ToString())) && /*blue scribbles to '&&'*/
(y => y.Element("brandname").Value.Equals(cbBrandName.SelectedItem.ToString()
))).Select(k => k.Element("price"
).Value).ToString();
My other question is that i want to make the selected values of cbProduct as distinct. The below code takes all the values instead of distinct values:
cbProduct.Items.AddRange(doc.Descendants("items"
).Select(x => x.Element("productname").Value
).ToArray<string>());//adds all products
cbProduct.SelectedIndex = 0;
giving any one answer is ok
Please assist me
Thanks in advance
It looks like you are passing 2 lambdas to the Where function and trying to logical-and (&&) them together. You can't do that. The && has to occur inside the Where lambda. Or you can chain 2 Where functions together. Something like this:
lblPrice.Text = doc.Descendants("items")
.Where(x => x.Element("productname").Value.Equals(cbProduct.SelectedItem.ToString()) &&
x.Element("brandname").Value.Equals(cbBrandName.SelectedItem.ToString()))
.Select(k => k.Element("price").Value).ToString();
The other issue I see is you are ending your query with a select, but never actually enumerating it. You probably want to do something like this:
lblPrice.Text = doc.Descendants("items")
.Where(x => x.Element("productname").Value.Equals(cbProduct.SelectedItem.ToString()) &&
x.Element("brandname").Value.Equals(cbBrandName.SelectedItem.ToString()))
.Select(k => k.Element("price").Value)
.FirstOrDefault();
Which will return the string you are looking for, or null if nothing exists (so you probably want to skip the final .ToString() call in this case, since you are already returning a string from Select and .ToString() on a null will throw an exception).
For the first question, it looks like you just want to select the one price. This code will work, assuming that the item is found by the .Single(). It will throw otherwise, in which case you should use .SingleOrDefault() and check for null on the found item.
lblPrice.Text =
doc.Descendants("items")
.Single(x => x.Element("productname").Value == cbProduct.SelectedItem.ToString() &&
x.Element("brandname").Value == cbBrandName.SelectedItem.ToString())
.Element("price").Value;
For the second question, you need to close off your .Select with a bracket, then you can call .Distinct() and .ToArray() to filter to distincts and project the result to string[]. I've also thrown an .OrderBy() in there, as there's nothing more annoying than a ComboBox in a random order. Try this:
cbProduct.Items.AddRange(doc.Descendants("items")
.Select(item => item.Element("productname").Value)
.Distinct()
.OrderBy(item => item)
.ToArray());
I have written a LINQ query with or condition in it, but its not working, it seem I am doing something wrong.
I am passing a string value and on it, I want to get my result.
var userDetails = context.tbl_members.Where
(
d => d.Mobile == value
||
d.MemberId == Int32.Parse(value)
).SingleOrDefault();
its not working if someone put a mobile no, but if work with memberID
if I split the query keep only mobile no its running fine.
var userDetails = context.tbl_members.Where(d => d.Mobile == value ).SingleOrDefault();
Please check what I did wrong with or condition
Regards
Moksha
var userDetails = context.tbl_members
.Where(d => d.Mobile == value ||
d.MemberId == Int32.Parse(value))
.SingleOrDefault();
It looks like you are using Linq to Entities or Linq to Sql. Int32.Parse() is not supported in that context - just do the number conversion before your query:
int numValue = Int32.Parse(value);
var userDetails = context.tbl_members
.Where(d => d.Mobile == value || d.MemberId == numValue)
.SingleOrDefault();
thanks for your help brokenGlass,
the error was in converting from string to int, as I was passing string of 10 digits, it was not getting converted into int
Value was either too large or too small for an Int32.
thanks