Converting SQL query result to Linq result with an new field that is not in the Model - sql

I have an SQL query,
SELECT
c.AssignedTo ,c.CampaignID, c.Name, c.Venue,c.StartedOn,
c.CompletedOn, c.IsOpen, COUNT(C.Name) AS Leads
FROM
Campaign AS c
RIGHT JOIN
Leads AS l ON l.CampaignID = c.CampaignID
GROUP BY
c.AssignedTo, c.CampaignID, c.Name,c.Venue,c.StartedOn, c.CompletedOn, c.IsOpen
ORDER BY
c.AssignedTo
These are my two tables in that query, CAMPAIGNS:
[Table("Campaigns")]
public class Campaigns
{
[Key]
public int CampaignID { get; set; }
[MaxLength(30)]
public string Name { get; set; }
[MaxLength(200)]
public string Venue { get; set; }
[ForeignKey("UsersReference")]
public int AssignedTo { get; set; }
public DateTime StartedOn { get; set; }
public DateTime? CompletedOn { get; set; }
public bool IsOpen { get; set; }
// To Reference Users table using FK
public Users UsersReference { get; set; }
}
and Leads:
[Table("Leads")]
public class Leads
{
[Key]
public int LeadID { get; set; }
[ForeignKey("CampaignsReference")]
public int CampaignID { get; set; }
[MaxLength(30)]
public string ConsumerName { get; set; }
[MaxLength(30)]
public string EmailAddress { get; set; }
[MaxLength(10)]
public string PhoneNo { get; set; }
public string PreferredMoC { get; set; }
public DateTime DateApproached { get; set; }
[ForeignKey("ProductsReference")]
public int ProductID { get; set; }
public string Status { get; set; }
// To access Campaign and Product table through FK
public Campaigns CampaignsReference { get; set; }
public Products ProductsReference { get; set; }
}
My query returns a result likes this in SQL:
The Leads column is just the COUNT() of the columns matching with my CampaignID. I've used context.Campaigns.FromSqlRaw() but since my Campaigns doesn't have another column specifically for the count.
Is there a way to display my new field Count() using EF Core and Linq?

Use LINQ Query for such task.
var query =
from l in ctx.Leads
let c = l.CampaignsReference
group c by new { c.AssignedTo, c.CampaignID, c.Name, c.Venue, c.StartedOn, c.CompletedOn, c.IsOpen } into g
select new
{
g.Key.AssignedTo,
g.Key.CampaignID,
g.Key.Name,
g.Key.Venue,
g.Key.StartedOn,
g.Key.CompletedOn,
g.Key.IsOpen,
Leads = g.Sum(x => x.Name != null ? 1 : 0)
};
var query = query.OrderBy(x => x.AssignedTo);

Related

SQL: Count elements in a joined table while using group by

Having written this question, C# + LinQ: get the total of elements of a related table, I am convinced I was not clear enough to get help (or at least I was not in the right direction for that), so I'll focus my question in a different way so to see if I get a start point.
My question was mainly about LinQ, and now I'll focus only on SQL and try to use a generalized way of asking, so please, don't mark it as duplicate again, because it is not.
Given the following tables, I need to list elements from TableA adding two columns counting how many elements from TableB and TableC has for each row:
TableA:
Column_name
Type
TableA_id
int
ForeignKey1
smallint
ForeignKey2
int
ForeignKey3
smallint
TableB:
Column_name
Type
TableB_id
int
ForeignKey1
smallint
ForeignKey2
smallint
ForeignKey3
int
TableC:
Column_name
Type
TableC_id
int
ForeignKey4
int
How tables are related:
For each TableA row, ForeignKey1 + ForeignKey2 + ForeignKey3 equals one row in TableB that needs to be count, in other words, I need to count the occurences of ForeignKey1 + ForeignKey2 + ForeignKey3 in TableB and display it as an extra "count" column in the TableA list.
Same, for each TableA row, I also need to count how many elements of the TableC belong to that row, taking into account that ForeignKey4 is the foreign key that links with TableB_id.
Saying it differently again, FK1 + FK2 + FK3 in TableA > one row in TableB, so TableA will have many related TableB rows and FK4 In TableC > one row in TableB, so in the end, one row in TableA will have x TableB and y TableC elements.
I hope I'm being clear now and get a SQL solution. Then I'll use it as a start point and try to translate it to LinQ.
This is what I was able to do so far:
With this next SQL query:
select a.tablea_id, a.foreignkey1, a.foreignkey2, a.foreignkey3, count(*) from TableA a
left join TableB b
on a.foreignkey1 = b.foreignkey1 and
a.foreignkey2 = b.foreignkey2 and
a.foreignkey3 = b.foreignkey3
group by a.tablea_id, a.foreignkey1, a.foreignkey2, a.foreignkey3
I am able to count elements from TableB for each TableA row, but I'm getting stuck with TableC part.
Edit 1: For #Svyatoslav Danyliv adding extra information so it's easier to help me:
Finca entity:
public partial class finca
{
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")]
public finca()
{
this.ps = new HashSet<ps>();
this.orden_trabajo = new HashSet<orden_trabajo>();
}
public int finca_id { get; set; }
public string descripcion { get; set; }
public System.DateTime fecha_creacion { get; set; }
public int direccion_id { get; set; }
public bool disponible_contratacion { get; set; }
public short concesion_id { get; set; }
public string codigo_gis { get; set; }
public string numero_alternativo { get; set; }
public Nullable<System.DateTime> fecha_ultima_inspeccion { get; set; }
public Nullable<decimal> latitud { get; set; }
public Nullable<decimal> longitud { get; set; }
public int acometida_defecto_id { get; set; }
public short planificacion_defecto_id { get; set; }
public int oficina_mas_cercana_id { get; set; }
public int ruta_defecto_id { get; set; }
public virtual concesion concesion { get; set; }
public virtual direccion direccion { get; set; }
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
public virtual ICollection<ps> ps { get; set; }
public virtual oficina oficina { get; set; }
public virtual planificacion planificacion { get; set; }
public virtual ruta ruta { get; set; }
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
public virtual ICollection<orden_trabajo> orden_trabajo { get; set; }
public virtual acometida acometida { get; set; }
}
Contrato entity:
public partial class contrato
{
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")]
public contrato()
{
this.contrato_clausula = new HashSet<contrato_clausula>();
this.contrato_file = new HashSet<contrato_file>();
this.contrato_tipo_facturacion = new HashSet<contrato_tipo_facturacion>();
this.incidencia_facturacion = new HashSet<incidencia_facturacion>();
this.reclamacion = new HashSet<reclamacion>();
this.deuda_externa = new HashSet<deuda_externa>();
this.contrato_ciclo = new HashSet<contrato_ciclo>();
this.contrato_campo_personalizado = new HashSet<contrato_campo_personalizado>();
this.ciclo_contrato_consumo_minimo = new HashSet<ciclo_contrato_consumo_minimo>();
this.contrato_historial = new HashSet<contrato_historial>();
this.convenio_contrato = new HashSet<convenio_contrato>();
this.convenio = new HashSet<convenio>();
this.orden_domiciliacion = new HashSet<orden_domiciliacion>();
this.contrato_coeficientes = new HashSet<contrato_coeficientes>();
this.ov_usuario_contrato = new HashSet<ov_usuario_contrato>();
this.sac_gestion = new HashSet<sac_gestion>();
this.expediente_morosidad = new HashSet<expediente_morosidad>();
this.contrato_tipo_contrato = new HashSet<contrato_tipo_contrato>();
this.adeudo_domiciliado = new HashSet<adeudo_domiciliado>();
this.contrato_tarjeta_bancaria = new HashSet<contrato_tarjeta_bancaria>();
this.contrato_estado_morosidad = new HashSet<contrato_estado_morosidad>();
this.contrato_cambio_email = new HashSet<contrato_cambio_email>();
this.ov_usuario_solicitud_cuenta = new HashSet<ov_usuario_solicitud_cuenta>();
this.cobro = new HashSet<cobro>();
this.devolucion_saldo = new HashSet<devolucion_saldo>();
this.contrato_consumo_historico_facturado = new HashSet<contrato_consumo_historico_facturado>();
this.notificacion_cobro_ventanilla = new HashSet<notificacion_cobro_ventanilla>();
this.grupo_gestor_cobro_contrato = new HashSet<grupo_gestor_cobro_contrato>();
this.tarjeta_bancaria_operacion = new HashSet<tarjeta_bancaria_operacion>();
this.factura = new HashSet<factura>();
this.orden_trabajo = new HashSet<orden_trabajo>();
this.grupo_gestor_cobro_contrato1 = new HashSet<grupo_gestor_cobro_contrato>();
}
public int contrato_id { get; set; }
public short tipo_contrato_id { get; set; }
public int ps_id { get; set; }
public int cliente_id { get; set; }
public short estado_contrato_idx { get; set; }
public Nullable<decimal> importe_fianza { get; set; }
public short idioma_comunicacion_id { get; set; }
public Nullable<int> direccion_emision_id { get; set; }
public string email_emision { get; set; }
public System.DateTime fecha_alta { get; set; }
public System.DateTime fecha_alta_solicitud { get; set; }
public Nullable<System.DateTime> fecha_baja { get; set; }
public Nullable<System.DateTime> fecha_solicitud_baja { get; set; }
public Nullable<short> relacion_inmueble_alta_idx { get; set; }
public bool cortable { get; set; }
public Nullable<long> contrato_file_id { get; set; }
public Nullable<int> ultimo_estado_morosidad_id { get; set; }
public Nullable<decimal> importe_pendiente_afavor { get; set; }
public Nullable<short> canal_cobro_idx { get; set; }
public Nullable<int> cliente_apoderado_alta_id { get; set; }
public Nullable<int> cliente_baja_id { get; set; }
public string referencia { get; set; }
public string observaciones { get; set; }
public bool excluir_facturacion_periodica { get; set; }
public Nullable<int> tipo_autorizado_baja_id { get; set; }
public Nullable<long> fichero_baja_id { get; set; }
public string observaciones_baja { get; set; }
public Nullable<System.DateTime> fecha_baja_prevista { get; set; }
public Nullable<bool> acepta_informacion_comercial { get; set; }
public bool exento_recargos { get; set; }
public int forma_envio_factura_id { get; set; }
public string aviso_al_lector { get; set; }
public Nullable<short> tipo_calibre_contratado_id { get; set; }
public Nullable<short> tipo_entidad_face_idx { get; set; }
public Nullable<int> oficina_contable_fe_id { get; set; }
public Nullable<int> organo_gestor_fe_id { get; set; }
public Nullable<int> unidad_tramitadora_fe_id { get; set; }
public Nullable<int> organo_proponente_fe_id { get; set; }
public short num_descargas_contrato_api { get; set; }
public bool gran_consumidor { get; set; }
public virtual cliente cliente { get; set; }
public virtual idioma idioma { get; set; }
public virtual direccion direccion { get; set; }
public virtual tipo_contrato tipo_contrato { get; set; }
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
public virtual ICollection<contrato_clausula> contrato_clausula { get; set; }
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
public virtual ICollection<contrato_file> contrato_file { get; set; }
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
public virtual ICollection<contrato_tipo_facturacion> contrato_tipo_facturacion { get; set; }
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
public virtual ICollection<incidencia_facturacion> incidencia_facturacion { get; set; }
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
public virtual ICollection<reclamacion> reclamacion { get; set; }
public virtual cliente cliente_apoderado_alta { get; set; }
public virtual cliente cliente_baja { get; set; }
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
public virtual ICollection<deuda_externa> deuda_externa { get; set; }
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
public virtual ICollection<contrato_ciclo> contrato_ciclo { get; set; }
public virtual file file { get; set; }
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
public virtual ICollection<contrato_campo_personalizado> contrato_campo_personalizado { get; set; }
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
public virtual ICollection<ciclo_contrato_consumo_minimo> ciclo_contrato_consumo_minimo { get; set; }
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
public virtual ICollection<contrato_historial> contrato_historial { get; set; }
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
public virtual ICollection<convenio_contrato> convenio_contrato { get; set; }
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
public virtual ICollection<convenio> convenio { get; set; }
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
public virtual ICollection<orden_domiciliacion> orden_domiciliacion { get; set; }
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
public virtual ICollection<contrato_coeficientes> contrato_coeficientes { get; set; }
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
public virtual ICollection<ov_usuario_contrato> ov_usuario_contrato { get; set; }
public virtual file fichero_baja { get; set; }
public virtual tipo_autorizado_baja tipo_autorizado_baja { get; set; }
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
public virtual ICollection<sac_gestion> sac_gestion { get; set; }
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
public virtual ICollection<expediente_morosidad> expediente_morosidad { get; set; }
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
public virtual ICollection<contrato_tipo_contrato> contrato_tipo_contrato { get; set; }
public virtual ps ps { get; set; }
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
public virtual ICollection<adeudo_domiciliado> adeudo_domiciliado { get; set; }
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
public virtual ICollection<contrato_tarjeta_bancaria> contrato_tarjeta_bancaria { get; set; }
public virtual contrato_estado_morosidad ultimo_contrato_estado_morosidad { get; set; }
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
public virtual ICollection<contrato_estado_morosidad> contrato_estado_morosidad { get; set; }
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
public virtual ICollection<contrato_cambio_email> contrato_cambio_email { get; set; }
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
public virtual ICollection<ov_usuario_solicitud_cuenta> ov_usuario_solicitud_cuenta { get; set; }
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
public virtual ICollection<cobro> cobro { get; set; }
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
public virtual ICollection<devolucion_saldo> devolucion_saldo { get; set; }
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
public virtual ICollection<contrato_consumo_historico_facturado> contrato_consumo_historico_facturado { get; set; }
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
public virtual ICollection<notificacion_cobro_ventanilla> notificacion_cobro_ventanilla { get; set; }
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
public virtual ICollection<grupo_gestor_cobro_contrato> grupo_gestor_cobro_contrato { get; set; }
public virtual forma_envio_factura forma_envio_factura { get; set; }
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
public virtual ICollection<tarjeta_bancaria_operacion> tarjeta_bancaria_operacion { get; set; }
public virtual tipo_calibre tipo_calibre { get; set; }
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
public virtual ICollection<factura> factura { get; set; }
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
public virtual ICollection<orden_trabajo> orden_trabajo { get; set; }
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
public virtual ICollection<grupo_gestor_cobro_contrato> grupo_gestor_cobro_contrato1 { get; set; }
}
Punto de suministro entity:
public partial class puntosuministroview
{
public int ps_id { get; set; }
public Nullable<int> contrato_id { get; set; }
public string razon_social { get; set; }
public string cliente_con_identificacion { get; set; }
public Nullable<System.DateTime> fecha_baja_contrato { get; set; }
public short concesion_id { get; set; }
public short planificacion_id { get; set; }
public Nullable<int> acometida_id { get; set; }
public string direccion_nombre_extendido { get; set; }
public Nullable<int> cliente_id { get; set; }
public string nombre_planificacion { get; set; }
public Nullable<short> ps_clasificacion_id { get; set; }
public short empresa_id { get; set; }
public string nombre_concesion { get; set; }
public short ps_activo_idx { get; set; }
public Nullable<int> ruta_id { get; set; }
public string ruta { get; set; }
public string identificacion { get; set; }
public Nullable<short> zona_id { get; set; }
public string nombre_zona { get; set; }
public string descripcion { get; set; }
public string codigo { get; set; }
}
From "puntosuministroview" concesion_id + planificacion_id + acometida_id identifies one Finca
From "contrato" ps_id identifies one puntodesuministroview.
What I need to a LinQ query where I list Fincas, but with two added columns where I count "puntosdesuministroview" and "contratos".
A row in tablea can have many entries in tableb, and a row in tableb can again have many entries in tablec. You want to show all tablea rows, each with their tableb and tablec counts.
In standard SQL you could simply join, aggregate and count as in the following query. The only thing to be aware of is that each tableb row appears multiple times in the joins to to them being linked to multiple tablec rows. So, count distinct tableb IDs to get the correct count.
select
a.*,
count(distinct b.tableb_id) as b_count,
count(c.tablec_id) as c_count
from tablea a
left outer join tableb b on b.foreignkey1 = a.foreignkey1
and b.foreignkey2 = a.foreignkey2
and b.foreignkey3 = a.foreignkey3
left outer join tablec c on c.foreignkey4 = b.tableb_id
group by a.tablea_id
order by a.tablea_id;
In SQL Server this is not possible, because this DBMS is not able to detect that grouping by the tablea's ID means it can show the complete row, as the ID uniqly identifies this data. (This is called functional dependency.) In SQL Server you can write above query, but the GROUP BY clause must contain all tablea columns. In the example:
group by a.tablea_id, a.foreignkey1, a.foreignkey2, a.foreignkey3
Another option is to do the aggregation step by step:
with c as
(
select foreignkey4, count(*) as cnt
from tablec
group by foreignkey4
)
, c_and_b as
(
select
b.foreignkey1, b.foreignkey2, b.foreignkey3,
count(*) as b_cnt,
coalesce(sum(c.cnt), 0) as c_cnt
from tableb b
left outer join c on c.foreignkey4 = b.tableb_id
group by b.foreignkey1, b.foreignkey2, b.foreignkey3
)
select
a.*,
coalesce(c_and_b.b_cnt, 0) as b_count,
coalesce(c_and_b.c_cnt, 0) as c_count
from tablea a
left outer join c_and_b on c_and_b.foreignkey1 = a.foreignkey1
and c_and_b.foreignkey2 = a.foreignkey2
and c_and_b.foreignkey3 = a.foreignkey3
order by a.tablea_id;
This latter query looks a lot more complicated than the first one. This is mainly because of the chain (a->b->c) where you want both the b and the c count. If b and c were independent from each other (say a = posts, b = upvotes, c = downvotes), then aggregating b and c and then joining those two results to table a would even be my preferred method. The query would still not look as slimlined as the first query, but would avoid other problems (mainly an unnecessarily big intermediate result plus aggregation problems when it's not only about counting, but about sums or averages).
If I understand what you are trying to do, this may help.
select a.tablea_id, a.foreignkey1, a.foreignkey2, a.foreignkey3, count(b.TableB_id) b_count, count(c.TableC_id) c_count
from
TableA a
left join TableB b on a.foreignkey1 = b.foreignkey1 and a.foreignkey2 = b.foreignkey2 and a.foreignkey3 = b.foreignkey3
left join TableC c on b.TableB_id = c.foreignkey4
group by a.tablea_id, a.foreignkey1, a.foreignkey2, a.foreignkey3

entity framework join 2 tables without modifying domain models

hey new to entity framework and i have these 2 models
SynchronizationProfile
public class SynchronizationProfileDBEntity
{
public string SyncProfileId { get; set; }
public string Code { get; set; }
public SynchronizationType SyncType { get; set; }
public string Schedule { get; set; }
public string UserName { get; set; }
}
SynchronizationLog
public class SynchronizationLogDBEntity
{
public string SyncLogId { get; set; }
public string SyncProfileId { get; set; }
public DateTime Ts { get; set; }
public SyncLogStatus LogStatus { get; set; }
}
there are no foreign keys on these because my team doesnt do it and get the results directly with LINQ
i want to get everything from SynchronizationLog(table) + Code(which is the name for everySyncProfileId) property from SynchronizationProfile
So i tried left join but for some reason dont get me the results.
var profiles = (from item in context.SynchronizationLogs
join item2 in context.SynchronizationProfiles
on item.SyncProfileId equals item2.SyncProfileId into gj
from subitem in gj.DefaultIfEmpty()
select new
{
SyncLogId = item.SyncLogId,
SyncProfileId = item.SyncProfileId,
Ts = item.Ts,
LogStatus = item.LogStatus
Code = item2.Code
}
Is my approach wrong?

Convert SQL query to Entity Framework which used AggregateFunctions and Where clause

How can I convert this query to Entity Framework?
SQL query:
SELECT Fullname, SUM(CoinCount+DiamondCount) AS GeneralPoint
FROM Students, Groups
WHERE Students.GroupId = Groups.Id AND Groups.Name = 'FSDA_1813_az'
GROUP BY Fullname
ORDER BY GeneralPoint
Entity:
public class Student
{
public int Id { get; set; }
public int GroupId { get; set; }
public string Fullname { get; set; }
public Nullable<int> DiamondCount { get; set; }
public Nullable<int> CoinCount { get; set; }
public string Phone { get; set; }
public string Address { get; set; }
public string Education { get; set; }
public string Email { get; set; }
public System.DateTime Birthdate { get; set; }
public string Username { get; set; }
public string Password { get; set; }
public Nullable<System.DateTime> LastVisited { get; set; }
public string Facebook { get; set; }
public string Linkedin { get; set; }
public string SocialMedia { get; set; }
public byte[] Photo { get; set; }
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
public virtual ICollection<Comment> Comments { get; set; }
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
public virtual ICollection<Exam> Exams { get; set; }
public virtual Group Group { get; set; }
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
public virtual ICollection<Point> Points { get; set; }
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
public virtual ICollection<StudentHomework> StudentHomeworks { get; set; }
}
UserRepository:
public ICollection<Student> GetUsersForGroup(string group)
{
using (var db = new EFContext())
{
var temp = db.Students.Where(x => x.Group.Name == group).ToList();
// I have to sort students in group by their DiamondCount+CoinCount as new GeneralCount
temp = temp.OrderBy(x => );
}
}
I have to sort students for their general point (DiamondCount+CoinCount).
But I can't send LINQ query by using Entity Framework. How can I do this?
Not tested but it should work:
var result = db.Students.Where(x => x.Group.Name == group)
.GroupBy(g => g.Fullname)
.Select(i => new
{
FullName = i.Key,
GeneralPoint = i.Sum(s => s.DiamondCount + s.CoinCount)
})
.OrderBy(o => o.GeneralPoint)
.ToList();

Linq query leading to invalid column name SqlException

ASPNET MVC5 web app, Visual Studio 2015
The website is language localized, so I need to get localized Categories depending on culture parameter.
The category_trans table accounts for providing category name translations while the ISO_Languages accounts for receiving a culture code parameter and passing its relating id the category_trans.
Models:
public partial class Product
{
public int? ID { get; set; }
public string Name { get; set; }
public string Description { get; set; }
public int CategoryID { get; set; }
public virtual category_trans category_trans { get; set; }
}
public partial class Category
{
public int ID { get; set; }
public string Name { get; set; }
public int? ParentID { get; set; }
public bool IsDeleted { get; set; }
}
public class category_trans
{
[Key]
[Column(Order = 1)]
public int category_id { get; set; }
[Key]
[Column(Order = 2)]
public int language_id { get; set; }
public string name { get; set; }
}
public class ISO_Languages
{
public int ID { get; set; }
public string code { get; set; }
public bool IsEnabled { get; set; }
public string name_en { get; set; }
public string name_fr { get; set; }
public string name_it { get; set; }
public string name_de { get; set; }
public string name_es { get; set; }
}
public static IQueryable<Product> ActiveProductsPerUser(BaseContext db, string userid, string culture)
{
return from p in db.Products
from ct in db.category_trans
from l in db.ISO_Languages
where (ct.category_id == p.CategoryID
&& ct.language_id == l.ID
&& l.code.Substring(0, 2) == culture)
select p;
}
results in an error:
System.Data.SqlClient.SqlException: Invalid column name 'category_trans_category_id'. Invalid column name 'category_trans_language_id'. in System.Data.SqlClient.SqlCommand.<>c.b__174_0(Task1 result)
in System.Threading.Tasks.ContinuationResultTaskFromResultTask2.InnerInvoke()
in System.Threading.Tasks.Task.Execute()
Please also note I am passing the expected result to another method for sorting and paging, thus accepting an IQueryable as input (no IEnumerable).
try this;
public static IQueryable<Product> ActiveProductsPerUser(BaseContext db, string userid, string culture)
{
var query = (from p in db.Products
join ct in db.category_trans
on p.CategoryID equals ct.category_id
join l in db.ISO_Languages
on ct.language_id equals l.ID
where l.code.Substring(0, 2) == culture)
select p).ToList();
return query;
}

Entity framework The column 'x' was specified multiple times for 'Filter1'

Developing Asp .Net MVC web application. Using Entity framework 6.1.1 and Visual Studio 2013.
Got this Linq:
Db.Distrule_contents.Where(x => x.distrule_id == DistruleId && x.Content.season_id.HasValue && x.Content.season.series_id == SeriesId).Select(x => x.Content).ToList();
and associated with DB tables classes:
[Table("distrule_content")]
public class Distrule_content
{
[Key,Column(Order=0)]
public int distrule_id { get; set; }
[Key, Column(Order = 1)]
[ForeignKey("Content")]
public string IDEC { get; set; }
public int status_id { get; set; }
public virtual Distrule Distrule { get; set; }
public virtual Content Content { get; set; }
public virtual Status Status { get; set; }
}
[Table("distrule")]
public class Distrule: CommonEntity
{
public string distrule_name { get; set; }
public DateTime? begin_date { get; set; }
public DateTime end_date { get; set; }
public int status_id { get; set; }
public int? minutes_to_tx { get; set; }
public string period_type { get; set; }
public bool? autoactivate_content { get; set; }
public virtual ICollection<Distrule_area> DistruleAreas { get; set; }
public virtual ICollection<Distrule_content> DistruleContent { get; set; }
public virtual ICollection<Distrule_georegion> DistruleGeoregion { get; set; }
public virtual Status status { get; set; }
}
[Table("content")]
public class Content
{
[Key]
public string IDEC { get; set; }
public DateTime? date_inserted { get; set; }
public DateTime? min_tx_date { get; set; }
public long? season_id { get; set; }
public int? episode_number { get; set; }
public string content_rus_name { get; set; }
public virtual Season season { get; set; }
}
[Table("status")]
public class Status: CommonEntity
{
public string status_name { get; set; }
}
As a Result receave this SQL Query:
SELECT
[Filter1].[distrule_id1] AS [distrule_id],
[Filter1].[IDEC1] AS [IDEC],
[Filter1].[date_inserted1] AS [date_inserted],
[Filter1].[min_tx_date1] AS [min_tx_date],
[Filter1].[season_id1] AS [season_id],
[Filter1].[episode_number1] AS [episode_number],
[Filter1].[content_rus_name1] AS [content_rus_name],
[Filter1].[season_id2] AS [season_id1]
FROM ( SELECT [Extent1].[distrule_id] AS [distrule_id1], [Extent1].[Distrule_Id] AS [distrule_id1], [Extent2].[IDEC] AS [IDEC1], [Extent2].[date_inserted] AS [date_inserted1], [Extent2].[min_tx_date] AS [min_tx_date1], [Extent2].[season_id] AS [season_id1], [Extent2].[episode_number] AS [episode_number1], [Extent2].[content_rus_name] AS [content_rus_name1], [Extent2].[season_Id] AS [season_id1], [Extent3].[series_id] AS [series_id1], [Extent3].[Series_Id] AS [series_id1], [Extent4].[season_id] AS [season_id2], [Extent4].[season_Id] AS [season_id2]
FROM [dbo].[distrule_content] AS [Extent1]
INNER JOIN [dbo].[content] AS [Extent2] ON [Extent1].[IDEC] = [Extent2].[IDEC]
LEFT OUTER JOIN [dbo].[Season] AS [Extent3] ON [Extent2].[season_Id] = [Extent3].[Id]
LEFT OUTER JOIN [dbo].[content] AS [Extent4] ON [Extent1].[IDEC] = [Extent4].[IDEC]
WHERE [Extent2].[season_id] IS NOT NULL
) AS [Filter1]
WHERE ([Filter1].[distrule_id1] = #p__linq__0) AND ([Filter1].[series_id1] = #p__linq__1)
And following error: The column 'distrule_id1' was specified multiple times for 'Filter1'.
What i am doing wrong?
update 2014-09-10
Solved after deep study EF navigation rules. Thx to chconger. Problem was in letting EF self realize where FK should be placed. So after adding everywhere ForeignKey attribute is worked fine.
Here how it looks now:
[Table("distrule_content")]
public class Distrule_content
{
[Key,Column(Order=0)]
public int distrule_id { get; set; }
[Key, Column(Order = 1)]
[ForeignKey("Content")]
public string IDEC { get; set; }
public int status_id { get; set; }
[ForeignKey("distrule_id")]
public virtual Distrule Distrule { get; set; }
[ForeignKey("IDEC")]
public virtual Content Content { get; set; }
[ForeignKey("status_id")]
public virtual Status Status { get; set; }
}
Couple of issues from what I can see.
1. You have a foreign key set above a mismatched string IDEC, instead
[Key, Column(Order = 1)]
[ForeignKey("Content")]
public virtual Content Content { get; set; }
2. You are missing a constructor with HashSets for your class Distrule
public Distrule()
{
DistruleAreas = new HashSet<DistruleArea>();
DistruleContents = new HashSet<DistruleContent>();
DistruleGeoregions = new HashSet<DistruleGeregion>();
}