NHibernate - Inner Join between different sessions (different connections) - c#

two different projects I want INNER JOIN statement to write out.
Include the second session of the results, but I can not get
using (ISession session = Con1.OpenSessiongeneral())
{
using (ISession session1 = Con2.OpenSessionsystem())
{
result = (from s in session.Query<AU_SalesTarget>()
join t in session.Query<AU_Terms>() on s.termId equals t.termId
join b in session1.Query<Branchs>() on s.branchId equals b.branchId
select new SalesTarget_Derogate
{
salesTargetId = s.salesTargetId,
mounth = t.month,
year = t.year,
calculateMethod = s.calculateMethod,
branchName = b.branchName
}).Skip(0).Take(50).ToList<SalesTarget_Derogate>();
}
}
list returns null

Im not sure why you get a null list, but you should use a store procedure if your SQL Server instance, support the join between different instances.
If is not supported, the solution is not elegant, you can try to get the data first, then use linq to join them like this:
using (ISession session = Con1.OpenSessiongeneral())
{
result = (from s in session.Query<AU_SalesTarget>()
join t in session.Query<AU_Terms>() on s.termId equals t.termId
select new
{
salesTargetId = s.salesTargetId,
mounth = t.month,
year = t.year,
calculateMethod = s.calculateMethod,
branchId = s.branchId
})
.Skip(0)
.Take(50)
.ToList();
}
var branchIds = result.Select(x => x.branchId)
.List();
Branchs bAlias = null;
IList<Branchs> branches = null;
using (ISession session1 = Con2.OpenSessionsystem())
{
branches = session1.QueryOver<Branchs>
.WhereRestrictionOn(x => x.branchId).IsIn(branchIds)
.Select(list => list
.Select(x => x.branchId).WithAlias(() => bAlias.branchId)
.Select(x => x.branchName).WithAlias(() => bAlias.branchName)
)
.TransformUsing(Transformers.AliasToBean<Branchs>())
.List<Branchs>();
}
result = result.Join(branches,
x => x.branchId,
x => x.branchId,
(x, y) => new SalesTarget_Derogate
{
salesTargetId = x.salesTargetId,
mounth = x.month,
year = x.year,
calculateMethod = x.calculateMethod,
branchName = y.branchName
}).ToList();

Related

Particular Query in Linq It does not perform the same thing as an inner join in SQL Server

This query is being carried out to take the zone and category names from the respective Product-related tables.
SELECT
Categoria.NombreCategoria,
Zona.ZonaGrupo,
p.NombreProducto,
p.ProductoTiene,
p.RealizadosEvento,
p.FechaInicial,
p.FechaFin
FROM
Productos p
INNER JOIN
Categoria ON p.CategoriaId = Categoria.Id
INNER JOIN
Zona ON p.ZonaId = Zona.ZonaId
The result of the SQL query returns the 1000 records that the products table must have with their zones and categories.
When doing the following in linq, it returns only 8 records ...
IQueryable<ProductosViewModel> ProductosMaped =
from p in Db.Productos
join g in Db.Zona on p.ZonaId equals g.ZonaId
join acr in Db.Categoria on p.CategoriaId equals acr.Id
select new ProductosViewModel
{
Categoria = acr.NombreCategoria,
ZonaGrupo = g.ZonaGrupo,
NombreProducto = p.NombreProducto,
ProductoTiene = p.ProductoTiene,
RealizadosEvento = p.RealizadosEvento,
FechaInicial = p.FechaInicial,
FechaFin = p.FechaFin,
};
I only need to link these 2 tables so that list only shows me CategoryName and ZoneName or Group Zone.
Better idea: Use Include with navigation properties:
List<ProductosViewModel> list = await this.Db.Productos
.Include( p => p.Zona )
.Include( p => p.Categoria )
.Where( p => p.Categoria != null && p.Zona != null ) // <-- This step may be optional depending on your database.
.Select( p => new ProductosViewModel
{
Categoria = p.Categoria.NombreCategoria,
ZonaGrupo = p.Zona.ZonaGrupo,
NombreProducto = p.NombreProducto,
ProductoTiene = p.ProductoTiene,
RealizadosEvento = p.RealizadosEvento,
FechaInicial = p.FechaInicial,
FechaFin = p.FechaFin,
} )
.ToListAsync()
.ConfigureAwait(false);

How to change in elegant way List<> structure

I am using LINQ to entitiy in my project.
I have this LINQ:
var result = (from inspArch in inspectionArchives
from inspAuth in inspArch.InspectionAuthority
select new
{
Id = inspArch.Id,
clientId = inspArch.CustomerId,
authId = inspAuth.Id
}).ToList();
After LINQ is executed result has this value :
Is there any elegant way (for example using LINQ or change above existing LINQ) to create from the list above, new list like that:
I haven't built this to see if it compiles, but this should work. You need to aggregate the Id and AuthId fields.
var result = (from inspArch in inspectionArchives
from inspAuth in inspArch.InspectionAuthority
select new
{
Id = inspArch.Id,
clientId = inspArch.CustomerId,
authId = inspAuth.Id
})
.GroupBy(g => g.clientId)
.select(s => new {
Id = string.Join(",", s.Select(ss => ss.Id.ToString())),
ClientId = s.Key,
AuthId = string.Join(",", s.Select(ss => ss.authId.ToString()).Distinct()),
}).ToList();
You need group by and you can apply String.Join on the resulting IGrouping:-
var result = (from inspArch in inspectionArchives
from inspAuth in inspArch.InspectionAuthority
group new { inspArch, inspAuth } by inspArch.CustomerId into g
select new
{
Id = String.Join(",",g.Select(x => x.inspArch.Id),
clientId = x.Key,
authId = String.Join(",",g.Select(x => x.inspAuth.Id)
}).ToList();
The tricky part here is to group both objects i.e. new { inspArch, inspAuth } because we need to access properties from both.
Update:
Since this is entity framework, it won't be able to translate the method String.Join to SQL, so we can bring back the grouped object to memory using AsEnumerable and then project it like this:-
var result = (from inspArch in inspectionArchives
from inspAuth in inspArch.InspectionAuthority
group new { inspArch, inspAuth } by inspArch.CustomerId into g
select g).AsEnumerable()
.Select(g => new
{
Id = String.Join(",",g.Select(x => x.inspArch.Id),
clientId = x.Key,
authId = String.Join(",",g.Select(x => x.inspAuth.Id)
}).ToList();

Linq Select Data based on a value in another table

I have the linq statements listed below and I want to restrict the records from one table based on the value in another table. This is the code I have which works:
using (context = new DocEntityConnection())
{
var Docs = context.tbDocsDetails.Where(md => md.IsCurrentDetails && md.tbDoc.StatusID == 9).ToList();
this.approves = context.tbDocApproves.ToList().Where(a => Docs.Select(x => x.DocID).ToList().Contains(a.DocID)).ToList();
return Docs.Select(md => GetDataItem(md)).ToList();
}
There is another table called tbDocStatus which has a DocId field too
I would like to only return records from tbDocDetails where tbDocdetails.DocId = tbDocStatus.DocId and tbDocStatus.StatusId = 4.
How would I add that to my code shown above?
That you need is a join
var Docs = from docDetail in context.tbDocsDetails
join docStatus in context.tbDocStatus
on docDetail.DocId = docStatus.DocId
where docStatus.StatusId == 4
select docDetail;
using (context = new DocEntityConnection())
{
var Docs = context.tbDocsDetails.Where(md => md.IsCurrentDetails && md.tbDoc.StatusID == 9).ToList();
var DocsFiltered = from d in Docs
join docStatus in context.tbDocStatus
on d.DocId equals docStatus.DocId
where docStatus.StatusId = 4
select d
this.approves = context.tbDocApproves.ToList().Where(a => Docs.Select(x => x.DocID).ToList().Contains(a.DocID)).ToList();
return DocsFiltered.Select(md => GetDataItem(md)).ToList();
}

The type of one of the expressions in the join clause is incorrect. Type inference failed in the call to 'GroupJoin'

I wanted to get sum of specific columns so I have used the group by in linq, but seems like I must getting the error in join. The datatypes of the fields are the same. This is not the original query but a made up one for Stack Overflow posting.
from T1 in TXPYTRANs
join T11 in ((from p in TXPYTRANs // geting error right here
group p by new { p.TRANTYPE, p.BILLYR, p.BILLNO } into g
select new
{
TRANAMT = g.Sum(b => b.TRANAMT),
TRANPENALTY = g.Sum(b => b.TRANPENALTY),
TRANINTEREST = g.Sum(b => b.TRANINTEREST),
TRANTYPE = g.Select(s => s.TRANTYPE),
BillYear = g.Select(s => s.BILLYR),
BillNumber = g.Select(s => s.BILLNO)
}).Take(100))
on new { BYr = T1.BILLYR, BNo = T1.BILLNO }
equals new { BYr = T11.BillYear, BNo = T11.BillNumber } into T12
from T13 in T12
select new
{
TranType = T13.TRANTYPE,
TranAmt = T13.TRANAMT,
TranPenalty = T13.TRANPENALTY,
TranInterest = T13.TRANINTEREST,
BillYr = T13.BillYr,
BillNo = T13.BillNo
}
You need
BillYear = g.Select(s=>s.BILLYR),
BillNumber = g.Select(s=>s.BILLNO)
to be
BillYear = g.Key.BILLYR,
BillNumber = g.Key.BILLNO
At the moment your Join selectors are
T1 => new { BYr = T1.BILLYR, BNo = T1.BILLNO }
T11 => new { BYr = T11.BillYear, BNo = T11.BillNumber }
and the properties of the second are IEnumerables of the types of the properties of the first, rather than matching the types.
(TRANTYPE should probably be the same.)

Joining two tables in linq method syntax, MVC EntityFramework

I'm working with two tables: CI_CLIENTRISK (SCD type 2)... and QB_INVOICES_HEADER (edmx screenshot).
They can be joined via ClientID. I want to essentially replicate this query:
SELECT a.ClientID,
MAX(b.InvoiceDt) AS MaxInvoiceDt
(omitted for brevity)
FROM CI_CLIENTRISKADJS a
INNER JOIN QB_INVOICES_HEADER b
ON a.ClientID = b.ClientID
WHERE a.IsActive = 1
GROUP BY a.ClientID
ORDER BY MaxInvoiceDt DESC
Here's what I have so far. It's not returning any records.
using (var db = new PLOGITENS01Entities())
{
var rvClientRiskAdjs = db.CI_CLIENTRISKADJS
.Take(50)
.Join(db.QB_INVOICES_HEADER,
a => a.ClientID,
b => b.ClientID,
(a, b) => new { Risk = a, Invoices = b })
.Where(a => a.Risk.IsActive == 1)
.OrderByDescending(o => o.Invoices.InvoiceDt)
.Select(c => new ClientRiskModel()
{
ClientRiskId = c.Risk.ClientRiskID,
ClientName = c.Risk.CI_CLIENTLIST.ClientName,
ClientId = c.Risk.ClientID,
ClientRiskAdjs = c.Risk.ClientRiskAdjs,
RecordValidStartDt = c.Risk.RecordValidStartDt,
RecordValidEnddt = c.Risk.RecordValidEnddt,
IsActive = c.Risk.IsActive
})
.ToList();
return View(new GridModel(rvClientRiskAdjs));
}
Try putting your .Take(50) method after your final .Select and before .ToList(). As it is, you are only taking the first 50 records of the first table and then joining from there. I'm assuming that there are no joins to the second table in the first 50 records of the first table; therefore, your result will have 0 records.
I stumbled across this solution from reading this post: https://stackoverflow.com/a/157919/1689144
var rvClientRiskAdjs = (from ri in db.CI_CLIENTRISKADJS
join qb in
(from qb in db.QB_INVOICES_HEADER
orderby qb.InvoiceDt ascending
group qb by qb.ClientID into grp
select new
{
InvoiceDt = grp.Max(s => s.InvoiceDt),
ClientID = grp.Key
})
on ri.ClientID equals qb.ClientID
orderby qb.InvoiceDt descending
where ri.IsActive == 1
select new ClientRiskModel()
{
ClientRiskId = ri.ClientRiskID,
ClientName = ri.CI_CLIENTLIST.ClientName,
ClientId = ri.ClientID,
ClientRiskAdjs = ri.ClientRiskAdjs,
RecordValidEnddt = ri.RecordValidEnddt,
RecordValidStartDt = ri.RecordValidStartDt
})
.ToList();

Categories

Resources