Duplicate values on join linq - c#

I am having some problem with the results, I get duplicates instead of two with different values on the join. The db contains those two values but one of them has different value inside the text field, how come I get duplicates, the only thing that is same is the CompanyPageId).
var query = (from pageEducation in _context.PageEducations
join companyPage in _context.Pages on pageEducation.CompanyPageId equals companyPage.Id into p
from companyPage in p.DefaultIfEmpty()
where pageEducation.PageId == pageId
select new PageEducation
{
Id = pageEducation.Id,
PageId = pageEducation.PageId,
CompanyPageId = pageEducation.CompanyPageId,
CustomCompany = pageEducation.CustomCompany,
CompanyPage = companyPage != null ? new Page {Name = companyPage.Name, Id = companyPage.Id} : null,
Education = pageEducation.Education
}).ToList();
My table looks like this:
CompanyPageId, education
33 edu1
33 edu2
and the result is list with two items but duplicates.
WHen i run this query in SQL i dont get any duplicates:
select * from Page_Educations
left join Pages on page_Educations.CompanyPageId = pages.Id
where page_Educations.PageId = 10
It even working when I run the linq in LinqPad
var query = from pageEducation in Page_Educations
join companyPage in Pages on pageEducation.CompanyPageId equals companyPage.ID into p
from companyPage in p.DefaultIfEmpty()
where pageEducation.PageId == 10
select new
{
Id = pageEducation.Id,
PageId = pageEducation.PageId,
CompanyPageId = pageEducation.CompanyPageId,
CustomCompany = pageEducation.CustomCompany,
CompanyPage = companyPage != null ? new {Name = companyPage.Name, Id = companyPage.ID} : null,
Education = pageEducation.Education
};
query.Dump();

Related

GridView Only populating 1 result

I'm currently working to add Data to a GridView. The data comes from 2 tables that are on different databases. Currently I am able to populate the first entry, but it does not populate past that. here is the code:
void FillOrder(int inv)
{
var _ord = new OrdersContext();
var _pro = new ProductContext();
var qryOrder = (from o in _ord.OrderDetails
where o.InvNumberId == inv
select new
{
o.ProductID,
o.Quantity
}).ToList();
foreach (var order in qryOrder)
{
int prodID = order.ProductID;
int itemCount = qryOrder.Count;
var qryProducts = (from p in _pro.Products
where p.ProductID == prodID
select new
{
p.ProductID,
p.ProductName
}).ToList();
var results = (from t in qryOrder
join s in qryProducts
on t.ProductID equals prodID
select new
{
t.ProductID,
t.Quantity,
s.ProductName
}).ToList();
OrderItemList.DataSource = results;
OrderItemList.DataBind();
}
}
Can anyone help as to why it's only populating the first entry?
If the number of products involved is relatively small, (and since this query seems to be relate to one invoice, I would think that is true), then you can probably use something like the code below.
This is removing the loop, but the contains method will probably generate a SQL statement something like select ProductID, ProductName from products where productID in (,,,,,,) so may fail if the number of parameters is extremely large.
var _ord = new OrdersContext();
var _pro = new ProductContext();
var qryOrder = (from o in _ord.OrderDetails
where o.InvNumberId == inv
select new
{
o.ProductID,
o.Quantity
}).ToList();
// Get the productIDs
var productIDS = qryOrder.Select(o=>o.ProductID).Distinct().ToList();
// Get the details of the products used.
var qryProducts = (from p in _pro.Products
where productIDS.Contains(p.ProductID)
select new
{
p.ProductID,
p.ProductName
}).ToList();
// Combine the two in memory lists
var results = (from t in qryOrder
join s in qryProducts
on t.ProductID equals s.ProductID
select new
{
t.ProductID,
t.Quantity,
s.ProductName
}).ToList();
OrderItemList.DataSource = results;
OrderItemList.DataBind();

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

Linq Query to get latest of eact defect ID

In al_jira_defect_out table i have Batch_Insert_Timestamp, AL_Defect_ID columns along with other columns.And In this table there will be duplicate AL_Defect_IDs with different Batch_Insert_Timestamp.
As per below code in linq i am getting all records which are Jira_Status == 0
var defects = (from d in db.al_jira_defect_out
join p in db.al_jira_ref_defect_project on d.Defect_Product_ID.ToString() equals p.al_product_id
join t in db.al_jira_ref_defect_type on d.Defect_Type_ID equals t.type
where d.Jira_Status == 0
select new Issue
{
fields = new CreateIssue
{
project = new Project
{
key = g.jira_project_key
},
issuetype = new Issuetype()
{
name = t.jira_equivalent
},
description = d.Defect_ShortDesc,
summary = d.Defect_DetailDesc,
versions = new List<Versions>
{
new Versions {name = d.Defect_Release_DetectedIn}
},
priority = new Priority
{
name = d.Defect_Severity_Name
},
customfield_10182 = d.AL_Defect_ID.ToString(),
}
}).Select().ToList();
i am getting record with AL_Defect_IDs duplicate.
But i required latest records[Max(d.Batch_Insert_Timestamp)] of each d.AL_Defect_ID with all required columns
can any one please help me to get linq query
If you group on AL_Defect_IDs, you can order by Batch_Insert_Timestamp and take the last (latest) one:
var defects = (from d in db.al_jira_defect_out
join p in db.al_jira_ref_defect_project on d.Defect_Product_ID.ToString() equals p.al_product_id
join t in db.al_jira_ref_defect_type on d.Defect_Type_ID equals t.type
where d.Jira_Status == 0
group new { d, p, t } on d.AL_Defect_ID into dptg
let dpt = (from dpt in dptg order by dpt.d.Batch_Insert_Timestamp select dpt).Last()
select new // ... whatever using dpt
Your sample code doesn't use p in the select, so you could leave it out of the grouping.

Join List Data from two separate Data Contexts

I have been searching for the solution to this problem and this is what I have so far:
var ProductInfo = (from p in twd.Products
orderby p.PC
where p.DELMARK == active
select p).AsEnumerable();
var BuyersData =
(from x in db.MinimumProductInfo
where x != null
orderby x.ItemCode, x.Region
let pnote =
(from pn in db.ProductNotes
where pn != null
where x.MinimumProductInfoID == pn.MinimumProductInfoID
&& pn.NoteTypeFlag == "p"
orderby pn.NoteDate descending
select pn).FirstOrDefault()
let cnote =
(from c in db.ProductNotes
where c != null
where x.MinimumProductInfoID == c.MinimumProductInfoID
&& c.NoteTypeFlag == "c"
orderby c.NoteDate descending
select c).FirstOrDefault()
let product =
(from p in ProductInfo
where x.ItemCode == p.PC
select p).FirstOrDefault()
select new ProductInfoWithNoteList
{
MinimumProductInfoID = x.MinimumProductInfoID,
ItemCode = x.ItemCode,
EquivCode = x.EquivCode,
Description = product.PDESC,
MinimumOnHandQuantity = x.MinimumOnHandQuantity,
MaximumOHandQuantity = x.MaximumOHandQuantity,
MinimumOrderQuantity = x.MinimumOrderQuantity,
LeadTimeInWeeks = x.LeadTimeInWeeks,
Region = x.Region,
Comment = cnote.ItemNote,
PermanentNote = pnote.ItemNote
}).ToArray();
It looks correct but I am getting an error,
'The specified LINQ expression contains references to queries that are
associated with different contexts.'
What this code is supposed to do is pull out all the active product codes from the first table using the twd datacontext then use data from that database in the db.MinimumProductInfo table. The reason they have 2 separate data contexts are they are completely different databases, the first is our ERP and the second is one that we are building in house.
What am I missing? I know it is possible to do this by separating the two datacontexts then adding them together because I have seen it done with single instances but I cannot find how to do it with list data.
Instead of this:
let product =
(from p in ProductInfo
where x.ItemCode == p.PC
select p).FirstOrDefault()
select new ProductInfoWithNoteList
{
MinimumProductInfoID = x.MinimumProductInfoID,
ItemCode = x.ItemCode,
EquivCode = x.EquivCode,
Description = product.PDESC,
MinimumOnHandQuantity = x.MinimumOnHandQuantity,
MaximumOHandQuantity = x.MaximumOHandQuantity,
MinimumOrderQuantity = x.MinimumOrderQuantity,
LeadTimeInWeeks = x.LeadTimeInWeeks,
Region = x.Region,
Comment = cnote.ItemNote,
PermanentNote = pnote.ItemNote
}).ToArray();
Try this by removing the let product clause and not filling the properties associated with ProductInfo because we will do that afterwards (See I have commented out the Description property):
select new ProductInfoWithNoteList
{
MinimumProductInfoID = x.MinimumProductInfoID,
ItemCode = x.ItemCode,
EquivCode = x.EquivCode,
//Description = product.PDESC,
MinimumOnHandQuantity = x.MinimumOnHandQuantity,
MaximumOHandQuantity = x.MaximumOHandQuantity,
MinimumOrderQuantity = x.MinimumOrderQuantity,
LeadTimeInWeeks = x.LeadTimeInWeeks,
Region = x.Region,
Comment = cnote.ItemNote,
PermanentNote = pnote.ItemNote
}).ToArray();
Now that you have your BuyersData and ProductInfo in memory, set the Description property or all the items in BuyersData:
foreach(var thisBuyerData in BuyersData)
{
var thisPi = ProductInfo.SingleOrDefault(x => x.PC == thisBuyerData.ItemCode);
thisBuyerData.Description = thisPi?.PDESC;
}

Count in select query of Linq to SQL

I am trying to convert below SQL query into Linq.
select eg.userid, eg.groupid, count(r.RID) as RecipientCount
from eg
join g on eg.groupid = g.groupid
join r on g.RID = r.RID
where eg.UserId = '7F813844-3B93-418E-8141-654082C4E37D'
and eg.IsDeleted = 0
and r.Isdeleted = 0
group by eg.groupid
Above query runs properly in SQL.
My Linq code is:
var v = from eml in dc.egs
join recpingroup in dc.g on eml.GroupID equals recpingroup.GroupID
where eml.aspnet_User.LoweredUserName.Equals(strUserName.ToLower())
&& !eml.IsDeleted
&& !recpingroup.r.IsDeleted
select new Info()
{
CreateDt = eml.CreateDt.ToShortDateString(),
UserId = eml.UserId.ToString(),
LastUpdateDt = eml.LastUpdateDt.ToShortDateString(),
Username = eml.aspnet_User.UserName,
GroupDescription = eml.GroupDescription,
GroupID = eml.GroupID.ToString().ToUpper(),
GroupName = eml.GroupName,
Count = dc.g.Count(r1 => r1.GroupID.Equals(eml.GroupID) && !r1.r.IsDeleted)
};
where dc is my DataContext.
But I am having problems in the last property i.e. Count is coming wrong. I want the counts of recipients from recpingroup.r as RecipientCount.
Also note that tables are linked in SQL internally by PK and FK references.
try following
Count = (from x in dc.g where(r1 => r1.GroupID.Equals(eml.GroupID) && !r1.r.IsDeleted) select x.g).count()

Categories

Resources