c# linq crm select where contains - c#

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).

Related

LinqToDB.LinqToDBException Expressionis not an association

Hi All I am trying to do below ,I want to load an attribute value like this .
var date = db.GetTable<bbb>().Where(x => idList.Contains(x.MID))
.Select(x => x.ModifiedDate).FirstOrDefault;
var test = db.GetTable<nnn>().Where(x => xguy.Distinct().Contains(x.SID))
.LoadWith(x => x.Modified == lastPostDate);
exception:-
LinqToDB.LinqToDBException: 'Expression '(x.Modified == value(vv.x+<>c__DisplayClass25_1).lastPostDate)' is not an association.'
How can I do this?
I used the FirstOrDefault option to get one value, but I do not understand about Expression is not an association.
Your use of the "LoadWith" method is suspicious here.
LoadWith is a specialized function to load additional table data that is linked (e.g. via foreign key) to the current table row.
Based on your usage, it looks like you're just trying to set up another "Where" clause, so instead of
.LoadWith(x => x.Modified == lastPostDate);
you wanted
.Where(x => x.Modified == lastPostDate);
or alternatively, combine this with your prior Where statement to simplify things:
var test = db.GetTable<nnn>().Where(x => x.Modified == lastPostDate &&
xguy.Distinct().Contains(x.SID));
Let me know if this isn't what you intended. If this is the case, perhaps you have an SQL statement or similar that you are now trying to translate to C# LINQ, or can otherwise explain in plain English what this statement was meant to accomplish?

Linq: Removing Group By but still get its items?

Just some details. Get Records is a variable where it contains the results of my stored procedure. Now, what I want to ask is what if I want to remove the group by function but I still want to get the key and items? Is there a way to do it?
var sortResCinema = GetRecords.Where(x => test2.branch == x.Bbranch && test.movieName == x.MovieName && x.MovieName != null)
.GroupBy(x => x.MovieName,
(key, elements) =>
new
{
Id = key,
Items = elements.ToList()
}).ToList();
There's no need for GroupBy here since you are looking for a specific movieName.
I guess you wanted something like this:
var sortResCinema = GetRecords.Where(x => test2.branch == x.Bbranch && test.movieName == x.MovieName).ToList();
You can replace the GroupBy with a Select. The Select statement can be used to alter the type of the results returned, which is what you appear to want to do. Should work with exactly the same syntax as the second parameter. So replace "GroupBy" with "Select" and remove the first argument. The key and elements properties that are being used in the GroupBy statement are internal to that function so you'd need to work out what function you want to replace these by, for instance the key might be x.MovieName.

Comparing a nullable column throws "Unable to cast the type..." exception

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 );

Navigate through entities in where clause

Im having some trouble writting a linq expression using entity framework. I have two related entities. Pago (payments) and Cuota(shares). In Cuota, I have the id_prestamo (loan id).
What I need is to get all the Pago(payments) for one Prestamo(loan). But as i have the Pago related only to Cuota, i have to get the id_prestamo from Cuota. The problem is that I cant navigate throw Cuota like this:
Lista_pagos = db.Pago.Where(x => x.Cuota.Prestamo.id_prestamo == prestamo.id_prestamo).ToList();
I tried also this expression but it doesnt work either:
Lista_pagos = db.Pago.Where(x => x.Cuota.Where(y => y.Prestamo.id_prestamo == prestamo.id_prestamo)).ToList();
When I say it doesn´t work is because I cannot compile the application. There must be an error in this place x.Cuota.Where(y => but don´t know how to use the where sentence right. I get this:
"The delegate does not take 1 argument"
Does anybody know how can i write this expression right?
I attach the entity relationship below.
Thanks!
You have a syntax error in your query.
db.Pago.Where()
...takes a predicate -- a function which returns bool.
x.Cuota.Where()
...returns IQueryable<Cuota>
So:
db.Pago.Where(x => x.Cuota.Where( ... ))
...is invalid code, because IQueryable<Cuota> is not bool.
I think what you actually want is:
Lista_pagos = db.Pago.Where(
x => x.Cuota.Any(y => y.Prestamo.id_prestamo == prestamo.id_prestamo)
).ToList();
(Note Any instead of Where.)
You have Cuotas for your Prestamos (by the way, Cuota is Installment, not Share, share is Acción) and you want all the Pagos for a given Prestamo:
Lista_Pagos = (from p in Pagos
join c in Cuotas
on p.Cuota.Cuota_Id equals c.Cuota_Id
where c.Prestamo.Prestamo_Id == prestamo.Prestamo_Id
select p).ToList<Pago>();

Where Predicates in LINQ

How can I specify conditions in Where predicates in LINQ without getting null reference exceptions. For instance, if q is an IQueryable how can I do like:
Expression<Func<ProductEntity,bool>> predicate = p => !search.CategoryId.HasValue || (search.CategoryId.HasValue && search.CategoryId == p.CategoryId);
var q2 = q.Where(predicate);
Here search is an object that holds possible search conditions that may or may not be set like search.CategoryId might not be set but if it is I want to get the products that are set by that condition.
When I do this I get null reference exceptions.
You can use the null-coalescing operator ?? to replace a possible null value with a default value. The following sets tries to match the search.Category if it exists or simply creates an "always true" expression. This will be optimized by any good Linq query provider (e.g. LinqToSql).
Expression<Func<ProductEntity,bool>> predicate = p => (search.CategoryId ?? p.CategoryId) == p.CategoryId);
var q2 = q.Where(predicate);
Another possibility would be to dynamically compose a query predicate using PredicateBuilder. That's the way I do it for searches with a similar pattern as you use:
var predicate = PredicateBuilder.True<Order>();
if (search.OrderId))
{
predicate = predicate.And(a => SqlMethods.Like(a.OrderID, search.OderID);
}
// ...
var results = q.Where(predicate);
Let's dissect the line:
Expression<Func<ProductEntity,bool> predicate = p => !search.CategoryId.HasValue
|| (search.CategoryId.HasValue && search.CategoryId == p.CategoryId)
var q2 = q.Where(predicate);
So how many ways can we get null problems?
search (your "captured" variable) could be null
p could be null, meaning there is a null in the list
you've handled the case of search.CategoryId being null (Nullable<T>)
but maybe p.CategoryId (the category on a record in the list) is null (Nullable<T>) - however, I'm not sure that this would cause a NullReferenceException
q (the list / source) could be null
So: out of 5 options you've eliminated 1; look at the other 4? There is also the definite possibility that the issue is caused by something invisible not shown in the code; for example the get could be:
public int? CategoryId {
get {return innerObject.CategoryId;}
}
and innerObject could be null; if you eliminate the other 4 (pretty easy to do), look at at this one as a last resort.

Categories

Resources