Navigate through entities in where clause - c#

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

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?

c# linq crm select where contains

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

siaqodb query: ArgumentException: The field handle and the type handle are incompatible

I am using the siaqodb plugin in Unity3D to manage my database game.
The plugin uses the System.LINQ library and I am having an specific problem:
The code:
var query = (from T t in siaqodb where t.Id == 1 select t);
return query.ToList<T> ()[0];
Works good! That's OK! Great!
But the code:
int a = 1;
var query = (from T t in siaqodb where t.Id == a select t);
return query.ToList<T> ()[0]
This code Throws the exception:
ArgumentException: The field handle and the type handle are incompatible.
I just solved my problem using the following code:
var query = (from T t in siaqodb select t);
return query.ToList<T> ().Where (t => t.Id == id).ToList ()[0];
This is not pretty but I could avoid the ArgumentException where I believe it happened in the Reflection code from siaqodb...
I came across with this error too, the problem seams to be that Generic types and Lamda expressions are incompatible in SQLite. The expression uses the Generic base type or interface, and is trying to get it from DB, but you are not storing the Base type or interface, you are storing a derivative. If you use lambdas, you have to use the correct type that matches the DB table.

EF: LINQ - orderby using child collection with condition - ArgumentException

I'm running into troubles trying to sort IQueryable of my EF Entity.
My object structure is something like this:
Item
Item.CustomFieldValue [List<CustomFieldValue>]
Item.CustomFieldValue.DefinitionID
Item.CustomFieldValue.Value
and I'm working with
IQueryable<Item>
I'd need to sort it conditionally with values having desired definition id being sorted first something like this:
queryable = queryable
.OrderBy(p => p.CustomFieldValue
.Where(p2 => p2.DefinitionID == defId)
.Select(p3 => p3.Value)
.OrderBy(p4 => p4)
);
This however throws ArgumentException "DbSortClause expressions must have a type that is order comparable.".
I indeed understand what's the exception trying to say to me, I just can't figure out on how to change this so that valid query is generated.
Any help greatly appreciated
EDIT:
To bring some more light into the issue, I want to achieve something similar that this query does
SELECT * FROM ticketnumber t, customfieldvalue c
WHERE t.id like '%00000047%' and c.ticketnumberid = t.id
ORDER BY CASE
WHEN DefinitionId = 2125 THEN 1
ELSE 2
END, c.Value ASC
Alternatively, as time is starting to become a factor for me, is there a way I could append OrderBy in string form?
You probably want to use FirstOrDefault() at the end of the end of the first OrderBy so you won't be dealing with enumerables but with values.
queryable = queryable
.OrderBy(p => p.CustomFieldValue
.Where(p2 => p2.DefinitionID == defId)
.Select(p3 => p3.Value)
.OrderBy(p4 => p4)
.FirstOrDefault()
);
Modification of Joanvo's answer did the trick, this is the working code [I've removed the inner OrderBy]
queryable = queryable.OrderBy(p => p.CustomFieldValue.Where(p2 => p2.DefinitionID == defId).Select(p3 => p3.Value).FirstOrDefault());

Dynamic Linq - Joining a table with 1 to many relationship

I'm using Dynamic Linq as the backend to an in-app reporting tool and I've hit a problem that I can't get round where I have to access a table that has a 1:M relationship .
My simplified data structure is this:
If I were querying this in standard Linq I'd write the query as:
from a in context.Table_A
select new
{
a.RefNo,
val = from b in a.Table_B
where (b.A_ID == a.ID)
where (b.code == "A0001"
select(b.Value).FirstOrDefault()
}
This works without any problem. However, when I try the query using Dynamic Linq I can't get the join to work.
From the code below you can see what I'm getting at but obviously I can't use the "a." and the "a.Table_B" references in the query. What do I have to do to be able to access Table_B in this context?
string select = "new (Ref_No,
val = from b in a.Table_B
where (b.A_ID == a.ID)
where (b.code == \"A0001\"
select(b.Value).FirstOrDefault()";
var results = context.Table_A.Select(select);
Edit 1:
To answer #Hogan's comment - Why don't I use join: The reports system is dynamic and the select statement may or may not be joining on to Table_B (or indeed joining on to Table_B multiple times) so the join has to be optional. My other issue with this is that unlike the Select method where I can pass in a string as a parameter (allowing me to make it dynamic quite easily) the Join() method can't be called in that way. The closest thing I've found is a dynamic Linq join extention method, something I may have to consider using but I've a feeling that this will be cumbersome with the dynamic select().
Edit 2:
Based on Hogan's suggestions I've got this far:
delegate string searchTableA(Table_A a);
public void Search()
{
....
searchTableA sel = (a) =>
{
return (from b in context.Table_B
where (b.A_ID == a.ID)
select (b.Value)).FirstOrDefault();
};
var res = context.Table_A.Select(sel);
}
This gives the error: 'System.Data.Entity.DbSet<TestDynamicLinqJoins.Table_A>' does not contain a definition for 'Select' and the best extension method overload 'System.Linq.Dynamic.DynamicQueryable.Select(System.Linq.IQueryable, string, params object[])' has some invalid arguments
Hard to give exact code because I don't know the types of your elements, but something like this would work fine using delegates.
delegate string searchTableA(elementType a);
searchTableA sel = (a) =>
{
return from b in a.Table_B
where (b.A_ID == a.ID)
where (b.code == "A0001")
select(b.Value).FirstOrDefault();
};
var results = context.Table_A.Select(sel);

Categories

Resources