Select all values from 2 tables - entity-framework

I have 3 tables code first, A and B and a join table (one to many relationship to link A and B), I would like to get all the results, not duplicate of the tables A and B and return it as selectList:
var a = from s in db.A
join ss in db.B on s.ps_id equals ss.ss_id
orderby s.ps_label
select new SelectListItem
{
Text = s.ps_id.ToString(),
Value = s.ps_label
};
return a;
This only returns results from the A table, but not from B as well. What is wrong, and what is your advice for best practice and performance for this?

Related

Is it possible to create a stream in ksqlDB to emit an ID that detects changes from 3 different tables that are joined together?

Is it possible to create a stream that detects changes on 3 different tables? For example, I have Table A which contains Ids for Table B and Table C. If I constructed my join query correctly. could I emit an event that contains Table A's id if there was a change in Table B or C?
Table A
id
b_id
c_id
field_abc
field_xyz
Table B
id
foo
Table C
id
bar
I want a stream that will emit Table A id's if there is any changes in any of those 3 tables. Is this possible?
For example, if fields field_abc, foo, or bar were to change, I want Table A's id to be emitted to a stream.
I recently ran into a similar issue as what you're describing. Currently this isn't possible using streams or tables due to limitations on ksqlDB. We did find a way to achieve the same results though.
Our solution was to create a custom query with the connector that creates a 3-way joined table and combines the updated fields on the 3 tables.
CREATE SOURCE CONNECTOR xyz_change WITH (
'connector.class' = '${v_connector_class}',
'connection.url' = '${v_connection_url}',
'connection.user' = '${v_connection_user}',
'connection.password' = '${v_connection_pass}',
'topic.prefix' = 'jdbc_abc_change',
'mode' = 'timestamp+incrementing',
'numeric.mapping' = 'best_fit',
'incrementing.column.name' = 'id',
'timestamp.column.name' = 'last_modified',
'key' = 'id',
'key.converter' = '${v_converter_long}',
'query' = 'select id, last_modified from(select a.id as id, GREATEST(a.last_modified, COALESCE(b.last_modified,from_unixtime(0)), COALESCE(c.last_modified,from_unixtime(0))) as last_modified from aaa a LEFT JOIN bbb b on a.fk_id = b.id LEFT JOIN ccc c on a.fk_id = c.id ) sub'
);
With this you're able to create any streams/tables you need off of it.

CriteriaBuilder - Subquery returns more than one result, when the expected result is only one

I am basically converting this query snippet:
I have a table A, and a table B (fk a.id), with a relationship where A can have many Bs.
I want to find A that is present in table B, which has values between X and Y.
Basically this query:
SELECT * FROM TABELA A AS a WHERE a.id IN (SELECT b.a_id FROM TABELA B AS B WHERE b.number_residents >= 100 AND b.number_residents <= 500)
Converting to criteria builder, I have this:
Subquery<HisCarAauuEntity> sub = cq.subquery(HisCarAauuEntity.class);
Root<HisCarAauuEntity> subRoot = sub.from(HisCarAauuEntity.class);
predicados.add(cb.in(aauu.get("id")).value(sub.select(subRoot.get("aId")).where(cb.and((cb.greaterThanOrEqualTo(subRoot.get("nResidents"), filtro.getNcargendesde()))), cb.lessThanOrEqualTo(subRoot.get("nResidents"), filtro.getNcargenhasta()))));
This works partially, because it returns me the result A that has the filter criteria, but if A has other rows in table B (that don't match the filter) it returns me that result too...
How do I make object A return the list of object B that contains ONLY the row that matches the filter sent?

UPDATE in postgresql with JOINS

I have a form where some input has a value that is made with this query:
SELECT e.tree.nombre
FROM d.p
JOIN e.theme ON id = id_capa
LEFT JOIN e.tree ON e.theme.id_tree = e.tree.id
WHERE id_capa = 816
e and d are schemas. The id_capa = 816 is passed as an argument to the query from the form that I'm editing. It returns a value correctly. Now I want to edit that value on my form, so I need to UPDATE but I have multiple tables, I read that I can't do an UPDATE with JOINS, how should I do that UPDATE?
In your original SQL query, the table d.p is not used, neither in SELECT nor in conditions. So it can be skipped; the query can be rewritten as:
SELECT e.tree.nombre
FROM e.theme
LEFT JOIN e.tree ON e.theme.id_tree = e.tree.id
WHERE e.theme.id = 816
Since the query selects values from table joined with LEFT JOIN, the result can be NULL, ie joined record from e.tree table can be missed. In this case there is nothing to update.
Existing matching record can be updated with the query:
UPDATE e.tree
SET nombre = <NEW_VALUE>
FROM e.theme
WHERE e.theme.id = 816 AND e.theme.id_tree = e.tree.id

LINQ to Entities returns null but generated SQL works fine

I have the following query which after executing sets the arts variable to null.
In SQL Server Profiler I can see the query is well formed, is being executed and is returning rows (there's only one thing to notice: the query includes all columns of all the tables involved).
Why the results collection is set to null even when the SQL query is working?
And why does the SQL query include all the columns and not only the ones specified in the anonymous type?
Thanks a lot.
Dial.
var arts = from rp in ent.ReportesDePrecios
join arp in ent.ArtículosDeReporteDePrecios on rp.Id equals arp.ReporteDePreciosId
//join crp in ent.CategoríasDeReporteDePrecios on rp.Id equals crp.ReporteDePreciosId
join a in ent.Artículos on arp.ArtículoId equals a.Id
where a.CategoríaId != null
join p in ent.Precios on new { Precio = a.Id, rp.ListaDePreciosId } equals new { Precio = p.ArtículoId, p.ListaDePreciosId }
where p.Activo == true
select new
{
CategoríaId = a.CategoríaId.Value,
a.FabricanteId,
ArtículoId = a.Id,
a.Código,
Precio = p.Valor
};
Sorry, one table was empty. That was one of the problems. Thanks a lot.

Convert SQL to LINQ, nested select, top, "distinct" using group by and multiple order bys

I have the following SQL query, which I'm struggling to convert to LINQ.
Purpose: Get the top 10 coupons from the table, ordered by the date they expire (i.e. list the ones that are about to expire first) and then randomly choosing one of those for publication.
Notes: Because of the way the database is structured, there maybe duplicate Codes in the Coupon table. Therefore, I am using a GROUP BY to enforce distinction, because I can't use DISTINCT in the sub select query (which I think is correct). The SQL query works.
SELECT TOP 1
c1.*
FROM
Coupon c1
WHERE
Code IN (
SELECT TOP 10
c2.Code
FROM
Coupon c2
WHERE
c2.Published = 0
GROUP BY
c2.Code,
c2.Expires
ORDER BY
c2.Expires
)
ORDER BY NEWID()
Update:
This is as close as I have got, but in two queries:
var result1 = (from c in Coupons
where c.Published == false
orderby c.Expires
group c by new { c.Code, c.Expires } into coupon
select coupon.FirstOrDefault()).Take(10);
var result2 = (from c in result1
orderby Guid.NewGuid()
select c).Take(1);
Here's one possible way:
from c in Coupons
from cs in
((from c in coupons
where c.published == false
select c).Distinct()
).Take(10)
where cs.ID == c.ID
select c
Keep in mind that LINQ creates a strongly-typed data set, so an IN statement has no general equivalent. I understand trying to keep the SQL tight, but LINQ may not be the best answer for this. If you are using MS SQL Server (not SQL Server Compact) you might want to consider doing this as a Stored Procedure.
Using MercurioJ's slightly buggy response, in combination with another SO suggested random row solution my solution was:
var result3 = (from c in _dataContext.Coupons
from cs in
((from c1 in _dataContext.Coupons
where
c1.IsPublished == false
select c1).Distinct()
).Take(10)
where cs.CouponId == c.CouponId
orderby _dataContext.NewId()
select c).Take(1);