LINQ to Xml not equal to operator - c#

I am using LINQ to XML. I want to use an equivalent of sql's <> operator in the where clause below....
var myBooks = from book in xDoc.Descendants("BOOKOB")
where book.Element("AUTHOR").Value
Please help!

Isn't != working?

As others have said, you can use != perfectly easily - don't forget that even when you're using LINQ, you're writing C#, not SQL.
You need to provide a value for it not to be equal to, of course, along with a select clause:
var myBooks = from book in xDoc.Descendants("BOOKOB")
where book.Element("AUTHOR").Value != "Jeff Atwood"
select book;
For simple queries like this, I usually find "dot notation" simpler to read:
var myBooks = xDoc.Descendants("BOOKOB")
.Where(b => b.Element("AUTHOR").Value != "Jeff Atwood");

You should be able to use != for not equal and == for equal to.

Related

How to properly use C# Linq to get a filtered list?

Say for example I have C# LINQ query as below:
var allBooks = from book in books
select book;
var booksNonFiction = allBooks.Where(x => x.Genre = NonFiction)
In this example, I want to obtain all the NonFiction titles in allBooks collection. Am a bit unsure about the lambda expression.
You can avoid the allbooks linq and this contains the same collection as books.
var booksNonFiction = books.Where(x => x.Genre == "NonFiction");
And if you want to order the data
var booksNonFiction = books.Where(x => x.Genre == "NonFiction").OrderBy(b => b.Title);
To understand the way how to think in lambda expression it helped me a lot to translate the "x =>" into "every x in the sequence"
In your example AllBooks is a sequence of books. So your statement:
var booksNonFiction = allBooks.Where(x => x.Genre == NonFiction)
would translate into: "From the sequence of all books, take "every book where book.genre equals nonfiction"
If you have more difficult linq statements it helps if you use plural nouns for your sequences (collections), and singular nouns for the parameters of the lambda expression (where you used x). This helps you remember the thing every x means.
var nonFictionBooks = allBooks.Where(book => book.Genre == NonFiction)
Here you can see that book is one element of the collection allBooks.
var frontPages = allBooks.Where(book => book.Genre == NonFiction)
.Select(book => book.FirstPage)
Even though you might not now the Select statement yet, you can understand that it means that from every "book" in the collection of allBooks, you should take book.FirstPage.
To help understand the possibilities of Linq the article The Standard Linq operators helped me to learn the most used Linq statements
Linq heavily leans on extension methods. If you are not familiar with this, the following might help: Extension Methods Demystified
You dont need first stement, because it says: enumerate all books and return them.
And also need method that actually enumerates collection, without it, it remains just a query.
var booksNonFiction = books.Where(x => x.Genre == NonFiction).ToList()
You just need a double =:
Where(x => x.Genre **==** NonFiction)
1.If Genre is Enum:
var booksNonFiction = allBooks.Where(x => x.Genre.Equals(Genre.NonFiction));
2.If Genre is a string:
var booksNonFiction = allBooks.Where(x => x.Genre.Equals("NonFiction"));

What is the proper AND operator in SQLite where statement

Using & or && in the where-statement? It seems it is not working.
can anyone help me with the Lambda expression on Sqlite query statement.
Thanks.
var existingItemUoM = db2.Table().Where(c => c.UoM == ItemNo & c.ItemNo == CodeforUoM).SingleOrDefault()
Since you seem to be using linq, the correct operator for AND is
&&
A good reference here are the 101 LINQ Samples.
The single & is a non-short-circuit and-operator. This means even if the first condition evaluates to true, the second condition will be checked (which isn't the case when using &&, the short-circuit and-operator).
Furthermore, in a real SQLite statement the correct expression for the boolean and-operator would be and, refer to the expressions of SQLite.
Correct operator for AND is &&, check with following where class
var existingItemUoM = db2.Table().Where((c => c.UoM) && (c.UoM == ItemNo) && (c.ItemNo == CodeforUoM)).SingleOrDefault()

Null coalesce not working in LINQ query

Take this:
int? item1 = null;
int? item2 = null;
someObjectList.Where(x => x.SomeItem1 == (item1 ?? x.SomeItem1)
&& x.SomeItem2 == (item2 ?? x.SomeItem2)
);
Where someObjectList is not empty and SomeItem1 and SomeItem2 is null in all the objects in the list.
Why is it returning nothing?
EDIT:
My Code:
public void GetPlacementsByMaterial(long clientMaterialID)
{
ClientMaterial clientMaterial = ((ApplicationEntityModel)NavigationItem.ObjectContext).ClientMaterial.FirstOrDefault(x => x.ClientMaterialID == clientMaterialID);
var list = GetPlacementList(supplier, mediaSpace);
PlacementsList = list.Where(x => x.MediaCategoryFormatID == (clientMaterial.MediaCategoryFormatID ?? x.MediaCategoryFormatID)
&& x.MediaCategorySizeID == (clientMaterial.MediaCategorySizeID ?? x.MediaCategorySizeID)
);
}
All ID's are Nullable<long>.
EDIT:
SQL Profiler:
SELECT *
FROM [dbo].[CampaignSchedulePlacements] AS [Extent5]
WHERE ([Extent5].[MediaCategoryFormatID] = [Extent5].[MediaCategoryFormatID]) AND ([Extent5].[MediaCategorySizeID] = [Extent5].[MediaCategorySizeID])
Note: cleaned up the `SQL.
In SQL, NULL is not equal to NULL.
You can interpret NULL as meaning: "there is value, but I don't know what it is". So if you're comparing two NULL values, you're really asking "is the first unknown value equal to the second unknown value?" Of course, there is no reason to assume they are, so SQL will say "no".
I am assuming that this is causing your problem. You can verify that by looking at the actual SQL produced. If it's using the SQL = operator, this is indeed the problem. You can verify that by running the SQL in a database tool, such as SQL Management Studio in case you're using SQL Server.
UPDATE:
The condition
([Extent5].[MediaCategoryFormatID] = [Extent5].[MediaCategoryFormatID])
will indeed return false when [Extent5].[MediaCategoryFormatID] is NULL.
That answers the question "Why is it returning nothing?"
However, another question come to mind: why would the entity framework generate that SQL from this linq query?
I'm afraid that linq to entities is not exactly known for the quality of its SQL generation, and this case seems to confirm that. You might consider Linq to SQL. Even if that seems to be a dead-end track in the long run, the current implementation if a lot better than linq to entities.
In either case, have you tried something like
someObjectList.Where(x =>
!item1.hasValue ||
x.SomeItem1.HasValue && x.SomeItem1.Value == item1.Value)
Make sure to verify that under the profiler as well though, linq to entities might mess it up too.

Best way to determined null or count 0

I have a iQueryable and I need to know if it's null or has no values.
IQueryable<people> L = (from p in people
where p.lastname.Contains("y")
select p);
if (L != null && L.Count() > 0) {
return "Something";
} else {
return "NOTHING";
}
Well if you use the L.Count() it will use more resources. Is there a better way? Something that does not use L.Count()
It's recommended that you use .Any().
IQueryable<people> L = (from p in people
where p.lastname.Contains("y")
select p);
if (L.Any()) {
return "Something";
} else {
return "NOTHING";
}
Does L need to be IQueryable<> ?
By using SingleOrDefault() it will be a single people (Person?) or null (presuming people is a class)
var result = (from p in people
where p.lastname.Contains("y")
select p).SingleOrDefault();
return result == null
? "NOTHING"
: "Something";
Other: Is SingleOrDefault() what you want to use or do you mean FirstOrDefault() or do you mean Any()?
Maybe LINQ: When to use SingleOrDefault vs. FirstOrDefault() with filtering criteria can help.
hth,
Alan.
An example of using the .Any method
return people.Any(p => p.lastname.Contains("y")) ? "something" : "nothing";
This is an example that would return an IQueryable if the .Any returns true, however it might be too ineffecient since it requires two round trips to the database. I'm sure a better method could be written, given enough time and thought.
return sis.Students.Any(p => p.LastName.Contains("y")) ?
people.Where(p => p.lastname.Contains("y")) : "nothing";
L.Any(), L.FirstOrDefault() will pretty much both have the same performance as they have almost identical implementation and are probably what you are looking for. Your SingleOrDefault is probably unintentional as it will throw an exception if there is more than one result.
Performance of LINQ Any vs FirstOrDefault != null
It's worth saying some of this depends on your provider. IQueryable just implies an intention. If It's Linq2Sql or something then yes L.Count() will request more resources - except that your also calling SingleOrDefault in the above line which means your null check is all you need, but your types don't match...
If I am running this statement against a Linq provider I write myself (or Amazons, or any other given LINQ provider) .Count() might be faster depending on what the provider is doing, but your assumptions hold if you're using the usual Microsoft Linq to SQL implementations.

Dynamic WHERE clause in LINQ

What is the best way to assemble a dynamic WHERE clause to a LINQ statement?
I have several dozen checkboxes on a form and am passing them back as: Dictionary<string, List<string>> (Dictionary<fieldName,List<values>>) to my LINQ query.
public IOrderedQueryable<ProductDetail> GetProductList(string productGroupName, string productTypeName, Dictionary<string,List<string>> filterDictionary)
{
var q = from c in db.ProductDetail
where c.ProductGroupName == productGroupName && c.ProductTypeName == productTypeName
// insert dynamic filter here
orderby c.ProductTypeName
select c;
return q;
}
(source: scottgu.com)
You need something like this? Use the Linq Dynamic Query Library (download includes examples).
Check out ScottGu's blog for more examples.
I have similar scenario where I need to add filters based on the user input and I chain the where clause.
Here is the sample code.
var votes = db.Votes.Where(r => r.SurveyID == surveyId);
if (fromDate != null)
{
votes = votes.Where(r => r.VoteDate.Value >= fromDate);
}
if (toDate != null)
{
votes = votes.Where(r => r.VoteDate.Value <= toDate);
}
votes = votes.Take(LimitRows).OrderByDescending(r => r.VoteDate);
You can also use the PredicateBuilder from LinqKit to chain multiple typesafe lambda expressions using Or or And.
http://www.albahari.com/nutshell/predicatebuilder.aspx
A simple Approach can be if your Columns are of Simple Type like String
public static IEnumerable<MyObject> WhereQuery(IEnumerable<MyObject> source, string columnName, string propertyValue)
{
return source.Where(m => { return m.GetType().GetProperty(columnName).GetValue(m, null).ToString().StartsWith(propertyValue); });
}
It seems much simpler and simpler to use the ternary operator to decide dynamically if a condition is included
List productList = new List();
productList =
db.ProductDetail.Where(p => p.ProductDetailID > 0 //Example prop
&& (String.IsNullOrEmpty(iproductGroupName) ? (true):(p.iproductGroupName.Equals(iproductGroupName)) ) //use ternary operator to make the condition dynamic
&& (ID == 0 ? (true) : (p.ID == IDParam))
).ToList();
I came up with a solution that even I can understand... by using the 'Contains' method you can chain as many WHERE's as you like. If the WHERE is an empty string, it's ignored (or evaluated as a select all). Here is my example of joining 2 tables in LINQ, applying multiple where clauses and populating a model class to be returned to the view. (this is a select all).
public ActionResult Index()
{
string AssetGroupCode = "";
string StatusCode = "";
string SearchString = "";
var mdl = from a in _db.Assets
join t in _db.Tags on a.ASSETID equals t.ASSETID
where a.ASSETGROUPCODE.Contains(AssetGroupCode)
&& a.STATUSCODE.Contains(StatusCode)
&& (
a.PO.Contains(SearchString)
|| a.MODEL.Contains(SearchString)
|| a.USERNAME.Contains(SearchString)
|| a.LOCATION.Contains(SearchString)
|| t.TAGNUMBER.Contains(SearchString)
|| t.SERIALNUMBER.Contains(SearchString)
)
select new AssetListView
{
AssetId = a.ASSETID,
TagId = t.TAGID,
PO = a.PO,
Model = a.MODEL,
UserName = a.USERNAME,
Location = a.LOCATION,
Tag = t.TAGNUMBER,
SerialNum = t.SERIALNUMBER
};
return View(mdl);
}
Just to share my idea for this case.
Another approach by solution is:
public IOrderedQueryable GetProductList(string productGroupName, string productTypeName, Dictionary> filterDictionary)
{
return db.ProductDetail
.where
(
p =>
(
(String.IsNullOrEmpty(productGroupName) || c.ProductGroupName.Contains(productGroupName))
&& (String.IsNullOrEmpty(productTypeName) || c.ProductTypeName.Contains(productTypeName))
// Apply similar logic to filterDictionary parameter here !!!
)
);
}
This approach is very flexible and allow with any parameter to be nullable.
You could use the Any() extension method. The following seems to work for me.
XStreamingElement root = new XStreamingElement("Results",
from el in StreamProductItem(file)
where fieldsToSearch.Any(s => el.Element(s) != null && el.Element(s).Value.Contains(searchTerm))
select fieldsToReturn.Select(r => (r == "product") ? el : el.Element(r))
);
Console.WriteLine(root.ToString());
Where 'fieldsToSearch' and 'fieldsToReturn' are both List objects.
This is the solution I came up with if anyone is interested.
https://kellyschronicles.wordpress.com/2017/12/16/dynamic-predicate-for-a-linq-query/
First we identify the single element type we need to use ( Of TRow As DataRow) and then identify the “source” we are using and tie the identifier to that source ((source As TypedTableBase(Of TRow)). Then we must specify the predicate, or the WHERE clause that is going to be passed (predicate As Func(Of TRow, Boolean)) which will either be returned as true or false. Then we identify how we want the returned information ordered (OrderByField As String). Our function will then return a EnumerableRowCollection(Of TRow), our collection of datarows that have met the conditions of our predicate(EnumerableRowCollection(Of TRow)). This is a basic example. Of course you must make sure your order field doesn’t contain nulls, or have handled that situation properly and make sure your column names (if you are using a strongly typed datasource never mind this, it will rename the columns for you) are standard.
System.Linq.Dynamic might help you build LINQ expressions at runtime.
The dynamic query library relies on a simple expression language for formulating expressions and queries in strings.
It provides you with string-based extension methods that you can pass any string expression into instead of using language operators or type-safe lambda extension methods.
It is simple and easy to use and is particularly useful in scenarios where queries are entirely dynamic, and you want to provide an end-user UI to help build them.
Source: Overview in Dynamic LINQ
The library lets you create LINQ expressions from plain strings, therefore, giving you the possibility to dynamically build a LINQ expression concatenating strings as you require.
Here's an example of what can be achieved:
var resultDynamic = context.Customers
.Where("City == #0 and Age > #1", "Paris", 50)
.ToList();

Categories

Resources