is ProjectTo < DTO > support Flattening? - asp.net-core

Code
_doctorRepository.Where(t => t.Id == doctorId).ProjectTo<EmploymentDTO>(_mapper.ConfigurationProvider).FirstOrDefault()
Mapping configuration
// doctor have Navigation property Hospital
CreateMap<Doctor, EmploymentDTO>().IncludeMembers(t => t.Hospital);
CreateMap<Hospital, EmploymentDTO>();
Expected behavior
SELECT TOP(1) [d].[Id], [d].[DepartmentId], [d].[DepartmentOther], [d].[DepartmentOtherCN], [d].[HospitalId], [d].[PositionId], [d].[PositionOther], [d].[PositionOtherCN], [d].[RankId], [d].[RankOther], [d].[RankOtherCN], [h].[City], [h].[Country], [h].[UniversityAffiliated], [h].[HospitalName], [h].[Province], [h].[CityCN], [h].[CountryCN], [h].[UniversityAffiliatedCN], [h].[HospitalNameCN], [h].[ProvinceCN]
FROM [Doctor] AS [d] WITH (NOLOCK)
LEFT JOIN [Hospital] AS [h] WITH (NOLOCK) ON [d].[HospitalId] = [h].[Id]
WHERE [d].[Id] = #__doctorId_0
Actual behavior :
not left join hospital Table
SELECT TOP(1) [d].[DepartmentId], [d].[DepartmentOther], [d].[DepartmentOtherCN], [d].[HospitalId], [d].[Id], [d].[PositionId], [d].[PositionOther], [d].[PositionOtherCN], [d].[RankId], [d].[RankOther], [d].[RankOtherCN]
FROM [Doctor] AS [d] WITH (NOLOCK)
WHERE [d].[Id] = #__doctorId_0

Related

Querying in Entity Framework

I need to translate that query to Entity Framework, can someone help me ?
select distinct
rap.AtracacaoData Atracacao,
loc.Nome_Local Local,
nav.Nome Navio,
nav.Navio_ID ViagemNavio,
'DT ' TransferenciaTipo,
edt.Numero TransferenciaNumero,
loct.Local Terminal
from
terminal..blalf bl (nolock)
inner join
terminal..navios nav (nolock) on nav.navio_id = bl.navio
inner join
terminal..avisochegada rap (nolock) on rap.Numero_Viagem_Ano = nav.Viagem_Ano_AVC
inner join
terminal..localatracalf loc (nolock) on loc.codigo_local = rap.armazem
inner join
tresos..vw_autorizacaorecebimento_navio autnav (nolock) on autnav.viagemnavio = nav.navio_id
and autnav.tipo = 2
inner join
tresos..edt edt (nolock) on edt.ID = autnav.DeclaracaoTransitoEntrada
inner join
tresos..localidades loct (nolock) on loct.ID = bl.terminal
union
select distinct
rap.AtracacaoData Atracacao,
loc.Nome_Local Local,
nav.Nome Navio,
nav.Navio_ID ViagemNavio,
'DTA ' TranferenciaTipo,
edt.Numero TransferenciaNumero,
loct.Local Terminal
from
terminal..blalf bl (nolock)
inner join
terminal..navios nav (nolock) on nav.navio_id = bl.navio
inner join
terminal..avisochegada rap (nolock) on rap.Numero_Viagem_Ano = nav.Viagem_Ano_AVC
inner join
terminal..localatracalf loc (nolock) on loc.codigo_local = rap.armazem
inner join
tresos..vw_autorizacaorecebimento_navio autnav (nolock) on autnav.viagemnavio = nav.navio_id
and autnav.tipo = 3
inner join
tresos..edta edt (nolock) on edt.ID = autnav.DeclaracaoTransitoEntrada
inner join
tresos..localidades loct (nolock) on loct.ID = bl.terminal
union
select distinct
rap.AtracacaoData Atracacao,
loc.Nome_Local Local,
nav.Nome Navio,
nav.Navio_ID ViagemNavio,
'PCI ' TranferenciaTipo,
edt.Numero TransferenciaNumero,
loct.Local Terminal
from
terminal..blalf bl (nolock)
inner join
terminal..navios nav (nolock) on nav.navio_id = bl.navio
inner join
terminal..avisochegada rap (nolock) on rap.Numero_Viagem_Ano = nav.Viagem_Ano_AVC
inner join
terminal..localatracalf loc (nolock) on loc.codigo_local = rap.armazem
inner join
tresos..vw_autorizacaorecebimento_navio autnav (nolock) on autnav.viagemnavio = nav.navio_id
and autnav.tipo = 4
inner join
tresos..eprc edt (nolock) on edt.ID = autnav.DeclaracaoTransitoEntrada
inner join
tresos..localidades loct (nolock) on loct.ID = bl.terminal
I tried to do but I couldn't do it.
First, you need an Entity Framework model that maps to your SQL structure. Hopefully you already have that. I'm assuming you do.
Second, you should create a DTO that has the properties your query will return:
public class ASensibleNameInYourDomain {
public ? Atracaco {get; set;}
public string Local {get; set;}
...
}
Third, you write a function that takes your EF DbContext and the query params, and returns a list of your DTO. It looks like your SQL is the same query repeated so I'd do:
public List<ASensibleNameInYourDomain> LoadFlightInfo(DbContext context, int autNavTipo, string transfericaTipo) {
return context.Blalf.Select(blaf=>
new ASensibleNameInYourDomain {
Atracacao=blaf.Navios.Avisochegada.AtracacaoData,
Local=blaf.Navios.Avisochegada.Localatracalf.Nome_Local,
Navio=blaf.Navios.Nome,
ViagemNavio=blaf.Navios.Navio_ID,
TransferenciaTipo=transfericaTipo,
TransferenciaNumero=blaf.Navios.Autorizacaorecebimento_navio.Numero,
Terminal=blaf.Localidades.Local
}
).Where(blaf=> blaf.Navios.Autorizacaorecebimento_navio.Tipo == autNavTipo)
.Distinct()
.ToList()
}
And then call it like so
public List<ASensibleNameInYourDomain> GetFlights(DbContext context) {
var result = LoadFlightInfo(context, 2, "DT");
result.addRange(LoadFlightInfo(context, 3, "DTA"));
result.addRange(LoadFlightInfo(context, 4, "PCI"));
return result
}
I think that'll do it, been a while since I did any C#...

DRUPAL db_or adding AND between multiple variables

I have inherited an application that is using the drupal filtering system to find results. The user can select to search the 'campus_location' column but when they enter multiple variables, it adds an AND between the condition.
Here is the printed version of the query generated by drupal:
SELECT * FROM champs c INNER JOIN users u ON u.uid = c.uid LEFT OUTER JOIN champs_rsvp r
ON r.uid = c.uid LEFT OUTER JOIN champs_checklists cl
ON cl.id = c.checklist_id LEFT OUTER JOIN node en
ON en.uid = u.uid AND en.type = 'getting_started_event'
LEFT OUTER JOIN node sn ON sn.uid = u.uid
AND sn.type = 'success_story'
LEFT OUTER JOIN champs_action_steps cas
ON cas.uid = u.uid
WHERE ( (c.campus_location LIKE 'Flint' ESCAPE '\\') )
**AND**( (c.campus_location LIKE 'Ann Arbor' ESCAPE '\\') )
I need the last AND to be an OR so it looks like this:
SELECT * FROM champs c INNER JOIN users u ON u.uid = c.uid LEFT OUTER JOIN champs_rsvp r
ON r.uid = c.uid LEFT OUTER JOIN champs_checklists cl
ON cl.id = c.checklist_id LEFT OUTER JOIN node en
ON en.uid = u.uid AND en.type = 'getting_started_event'
LEFT OUTER JOIN node sn ON sn.uid = u.uid
AND sn.type = 'success_story'
LEFT OUTER JOIN champs_action_steps cas
ON cas.uid = u.uid
WHERE ( (c.campus_location LIKE 'Flint' ESCAPE '\\') )
OR( (c.campus_location LIKE 'Ann Arbor' ESCAPE '\\') )
Which produces the correct results.
Here is the code that I inherited where it looks over the words in the search box. I just can't seem to figure out where it is adding the variables where it is putting the AND.
$words = explode(",", $_SESSION['form_state']['values']['filter']);
foreach($words as $word)
{
$or = db_or();
foreach($cols as $col)
{
$table = 'c';
if(in_array($col, array('completed_date', 'score')))
$table = 'cl';
elseif(in_array($col, array('name', 'mail')))
$table = 'u';
elseif($col == 'date')
$table = 'r';
elseif(in_array($col, array('announce', 'num_success_stories', 'num_action_steps'))) //can't put these in WHERE clause. Need to go in HAVING.
continue;
echo $word;
$or = $or->condition($table . '.' . $col, champs_make_like_sql($word), 'LIKE');
}
$result = $query->condition($or);
}

Left outter join linq

How do i change the training events into a left outer join in training events im very basic at linq so excuse my ignorance its not retrieve records that don't have any trainnevent reference attached to it
var q = from need in pamsEntities.EmployeeLearningNeeds
join Employee e in pamsEntities.Employees on need.EmployeeId equals e.emp_no
join tevent in pamsEntities.TrainingEvents on need.TrainingEventId equals tevent.RecordId
where need.EmployeeId == employeeId
where need.TargetDate >= startdate
where need.TargetDate <= enddate
orderby need.TargetDat
It's best to use where in combination with DefaultIfEmpty.
See here: LEFT JOIN in LINQ to entities?
var query2 = (
from users in Repo.T_Benutzer
from mappings in Repo.T_Benutzer_Benutzergruppen.Where(mapping => mapping.BEBG_BE == users.BE_ID).DefaultIfEmpty()
from groups in Repo.T_Benutzergruppen.Where(gruppe => gruppe.ID == mappings.BEBG_BG).DefaultIfEmpty()
//where users.BE_Name.Contains(keyword)
// //|| mappings.BEBG_BE.Equals(666)
//|| mappings.BEBG_BE == 666
//|| groups.Name.Contains(keyword)
select new
{
UserId = users.BE_ID
,UserName = users.BE_User
,UserGroupId = mappings.BEBG_BG
,GroupName = groups.Name
}
);
var xy = (query2).ToList();
Which is equivalent to this select statement:
SELECT
T_Benutzer.BE_User
,T_Benutzer_Benutzergruppen.BEBG_BE
-- etc.
FROM T_Benutzer
LEFT JOIN T_Benutzer_Benutzergruppen
ON T_Benutzer_Benutzergruppen.BEBG_BE = T_Benutzer.BE_ID
LEFT JOIN T_Benutzergruppen
ON T_Benutzergruppen.ID = T_Benutzer_Benutzergruppen.BEBG_BG

INNER JOIN LEFT JOIN in LINQ to SQL

How to convert INNER JOIN and LEFT JOIN in the following SQL query to LINQ to SQL? Thanks!
SELECT transactions.postdate,
transactions.clientkey AS TransClientKey,
transactions.type AS TransType,
clients.clientno,
Isnull(clients.nostmt, 0) AS CliNoStmt,
Isnull(aging.nostmt, 0) AS AgeNoStmt,
pmtchecks.*
FROM ((pmtchecks
INNER JOIN transactions
ON pmtchecks.transkey = transactions.transkey)
INNER JOIN clients
ON transactions.clientkey = clients.clientkey)
LEFT JOIN aging
ON ( transactions.clientkey = aging.clientkey )
AND ( pmtchecks.debtorkey = aging.debtorkey )
WHERE ( pmtchecks.debtorkey = 36927 )
AND ( transactions.status = 0 )
AND ( transactions.postdate <= '31-May-2012' )
AND ( ( transactions.postdate >= '01-May-2012' )
OR ( clients.clientno = 'UNKNOWN' ) )
ORDER BY pmtchecks.checkdate,
pmtchecks.checkno
Hi this is kind of dummy code i cnt say its exactly right but the idea will be exactly same to get the result
var anonymousType= (from pm in pmtchecks
join tr in transactions
on pm.transkey equals tr.transkey //INNERJOIN
join cl in clients
on tr.clientKey equals cl.clientKey
join ag in aging
on pm.debtorkey equals ag.debtorKey into ljoin //Left Join
from lj in ljoin.DefaultOrEmpty()
where pm.debortkey==36927 && tr.status==0 && tr.postdate<="31-May-2012" && tr.postdate>="01-May-2012" //u will have to change this to date format first
Select new {PostDate=tr.postdate, TransClientKey=tr.clientkey,TransType=tr.type,ClientNo=cl.clientno,CliNoStmt=cl.nomst ?? 0,AgeNoStmt=ag.nomst ??0,Pmtchecks=pm } //Anonymous type from this you can extract the values and fill to your custom type
).OrderBy(o=>o.Pmtchecks.checkdate).OrderBy(o=>o.Pmtchecks.checkno).ToList();
Hope this will help.
LINQ Query Samples
EDITED
var pmtchecks = from p in urcontext.pmtchecks
join t in urcontext.transactions on p.transkey equals t.transkey
join a in urcontext.aging on t.clientkey equals a.clientkey into details
from d in details.Where( a => ( a.debtorkey == p.debtorkey)).DefaultIfEmpty()
where (p.debtorkey == 36927 && t.status == 0 && t.postdate <= '31-May-2012'
&& (t.postdate >= '01-May-2012' || c.clientno == 'UNKNOWN' ))
orderby p.checkdate, p.checkno
select new
{
t.postdate,
t.clientkey,
// TransClientKey = t.clientkey, //only works if TransClientKey is property
t.type ,
//TransTypet = t.type ,//property
c.clientno,
c.nostmt,
//CliNoStmt = c.nostmt ?? 0,//property
a.nostmt//,
//AgeNoStmt = nostmt ?? 0,//property
//p. ... //follow above for p columns
};

Complex SQL to LINQ conversion with subquery

I am trying to convert this expression into LINQ from SQL, but a bit too difficult for me, maybe you can help me with this!
SELECT TOP (2) RecipeID, UserID, Name, Servings, PreparationTime, TotalTime, DifficultyLevelID, CuisineID, DishID, MainIngredientID, PriceLevelID, FlavourID, Instructions,
Notes, Thumbnail, VideoLink
FROM dbo.Recipes
WHERE (RecipeID NOT IN
(SELECT DISTINCT Recipes_1.RecipeID
FROM dbo.Allergies INNER JOIN
dbo.UsersAllergies ON dbo.Allergies.AllergyID = dbo.UsersAllergies.AllergyID INNER JOIN
dbo.IngredientsAllergies ON dbo.Allergies.AllergyID = dbo.IngredientsAllergies.AllergyID INNER JOIN
dbo.Ingredients ON dbo.IngredientsAllergies.IngredientID = dbo.Ingredients.IngredientID INNER JOIN
dbo.RecipesIngredients ON dbo.Ingredients.IngredientID = dbo.RecipesIngredients.IngredientID INNER JOIN
dbo.Recipes AS Recipes_1 ON dbo.RecipesIngredients.RecipeID = Recipes_1.RecipeID INNER JOIN
dbo.Users ON dbo.UsersAllergies.UserID = dbo.Users.UserID INNER JOIN
dbo.AllergyFactors ON dbo.IngredientsAllergies.AllergyFactorID = dbo.AllergyFactors.AllergyFactorID
WHERE (dbo.Users.UserID = 3) AND (dbo.AllergyFactors.AllergyFactorID < 3)))
It would be easier to help you if you showed us what you have already tried, but a Linq expression like this should give you the same result set
var query = (from rec in context.Recipes
where !(from al in context.Allergies
from ua in context.UsersAllergies.Where(x => al.AllergyID == x.AllergyID)
from ia in context.IngredientsAllergies.Where(x => al.AllergyID == x.AllergyID)
from in in context.Ingredients.Where(x => ia.IngredientID == x.IngredientID)
from ri in context.RecipesIngredients.Where(x => in.IngredientID == x.IngredientID)
from re in context.Recipes.Where(x => ri.RecipeID == x.RecipeID)
from us in context.Users.Where(x => ua.UserID == x.UserID)
from af in context.AllergyFactors.Where(x => ia.AllergyFactorID == x.AllergyFactorID)
where us.UserID == 3 && af.AllergyFactorID < 3
select re.RecipeID)
.Distinct()
.Contains(rec.RecipeID)
select new
{
rec.RecipeID,
rec.UserID,
rec.Name,
rec.Servings,
rec.PreparationTime,
rec.TotalTime,
rec.DifficultyLevelID,
rec.CuisineID,
rec.DishID,
rec.MainIngredientID,
rec.PriceLevelID,
rec.FlavourID,
rec.Instructions,
rec.Notes,
rec.Thumbnail,
rec.VideoLink
}).Take(2);