I've tried to figure it out why it is slow when I join 4 tables together by using Linq in C#. Furthermore, there are two the same tables wp_posts. I would like to know if I could reduce that tables it might be faster. I am using MySQL.
var results = from a in _newsEntities.wp_posts
join b in _newsEntities.wp_postmeta
on a.ID equals b.post_id
join c in _newsEntities.wp_posts
on b.meta_value equals c.ID.ToString()
join d in _newsEntities.wp_users on a.post_author equals d.ID
where a.post_status == "publish" &&
a.post_type == "post" &&
b.meta_key == "reporter_name"
select new
{
Id = a.ID,
Status = a.post_status,
Content = a.post_content,
ReporterId = c.post_content,
ReporterName = c.post_title,
DateCreated = a.post_date,
DateModified = a.post_modified,
AuthorId = a.post_author,
AuthorName = d.display_name
};
Related
I'm working on this conference app where I have to return certain values from the different table using join queries using LINQ
from a in db.ApplySchedule
join b in db.userdetails on a.UserID equals b.UserId
join c in db.roomdetails on a.RoomID equals c.RoomId
join d in db.VideoFiles on a.RoomID equals d.RoomId where d.IsActive == true || d.IsActive==false
join e in db.ImageFiles on a.RoomID equals e.RoomId where e.IsActive == true|| e.IsActive==false
where EntityFunctions.TruncateTime(a.MDate) == EntityFunctions.TruncateTime(DateTime.Now) && a.RoomID == id
&& a.Status == true
select new ShedulerViewModel
{
Id = a.BookingID,
UserId = a.UserID,
Uname = b.UserName,
RoomId = a.RoomID,
Rname = c.RoomName.ToUpper(),
Organizer = a.SubjectDetail,
Date = a.MDate,
FromTime = a.start_date,
ToTime = a.end_date,
//Accesseries = a.Accesseries,
attend = a.Attend,
VideoID = d.RoomId,
VideoPath = d.FilePath,
videoIsActive= d.IsActive,
ImageId = e.RoomId,
ImagePath = e.FilePath,
ImageIsActive = e.IsActive
};
Here is the problem, I'm able to get the values if the last two tables db.imagefiles and db.videofiles has matching values but incase it doesn't I'm getting 0 value from all the other tables even though there are rows with matching id, how do I overcome this? I want to pass value even if the video and image tables have no rows.
I am working with some SQL that has been provided and I am running into an issue where the count in the LINQ is different from the count in the SQL and would appreciate some help if possible.
The original SQL that was given is pretty poorly arranged and has a large number of nested queries. This being one of them. I have broken the query down into its main component and am now stitching it back together with LINQ.
The SQL that I am working with is here :
DECLARE #QSCollectionId UNIQUEIDENTIFIER = 'f52ec043-b360-4266-f95f-08d7c66074pe';
SELECT fieldid
Count(fieldid) AS fieldcount,
Sum(CASE
WHEN answer = [value] AND Answer IS NOT NULL THEN 1
ELSE 0
END) AS FieldAnswerMatchCount
FROM (SELECT DISTINCT FCI.fieldid,
answer,
QSA.qsrid,
FAG.fieldid AS dependentfield,
FAG.value
FROM forms.fieldconstraints FCI
INNER JOIN forms.sectionfieldmappings SFM
ON FCI.fieldid = SFM.fieldid
INNER JOIN forms.qssectionmappings QSSM
ON SFM.sectionid = QSSM.sectionid
INNER JOIN sessions.qsr
ON QSSM.qsid = qsr.qsid
--AND Qsr.QSCollectionId=#QSCollectionId
LEFT JOIN forms.answerguides FAG
ON
FCI.dependantanswerguideid = FAG.answerguideid
LEFT JOIN sessions.qsranswers QSA
ON FAG.fieldid = QSA.fieldid
AND Qsr.QsrId = QSA.qsrid
) AS
FieldConstr
GROUP BY fieldid
The LINQ
var id = Guid.Parse("f52ec043-b360-4266-f95f-08d7c66074be");
var firstResultPartThree = (from fci in FieldConstraints
join sfm in SectionFieldMappings on fci.FieldId equals sfm.FieldId
join qssm in QSSectionMappings on sfm.SectionId equals qssm.SectionId
join qsr in QSRs on new { qssm.QSId } equals new { qsr.QSId }
join ag in AnswerGuides on fci.DependantAnswerGuideId equals ag.AnswerGuideId into agResult
from agJoin in agResult.DefaultIfEmpty()
join qsrAnswers in QSRAnswers on new { agJoin.FieldId, qsr.QsrId } equals new {qsrAnswers.FieldId, qsrAnswers.QsrId} into qsrAnswersResult
from qsrAnswersJoin in qsrAnswersResult.DefaultIfEmpty()
//where qsr.QSCollectionId == id
select new {
FieldId = fci.FieldId,
Answer = qsrAnswersJoin.Answer,
QsrId = (Guid?)qsrAnswersJoin.QsrId,
DependentFieldId = agJoin.FieldId,
Value = agJoin.Value
}
);
firstResultPartThree.Dump();
var firstResultPartTwo = (from fr in firstResultPartThree
where fr.FieldId == Guid.Parse("98CA6B6F-4070-4CEB-E9F1-08D7C66278F9")
group fr by fr.FieldId into grp
select new {
FieldId = grp.Key,
Fieldcount = grp.Count(),
FieldAnswerMatchCount = grp.Count(x => (Guid?)grp.Key.Value != null)
}
);
The result of the LINQ in the example below gives me
FieldId | fieldcount | FieldAnswerMatchCount
98ca6b6f-4070-4ceb-e9f1-08d7c66278f9 | 4 | 4 |
The result of the sql for the same data is
98ca6b6f-4070-4ceb-e9f1-08d7c66278f9 | 3 | 2 |
The area that I am struggling with is
select new {
FieldId = grp.Key,
Fieldcount = grp.Count(),
FieldAnswerMatchCount = grp.Count(x => (Guid?)grp.Key.Value != null)
I understand that the count in the select is wrong, however I do not know how I need to correct it and would be grateful for some help.
I'm using Linq (code-first approach) query to retrieve the data from DB and couldn't able to get similar result while using below linq query:
from msi in db.MainSaleInvoiceTbls
join dsi in db.DetialSaleInvoiceTbls on msi.Id equals dsi.MainSaleInvoiceId
join ca in db.CustomerAccounts on msi.CustomerId equals ca.Id
join cg in db.MiscLists on ca.CustomerGroupId equals cg.Id
where msi.IsActive == true && msi.CompanyId == UniversalInfo.UserCompany.Id && msi.MainSaleInvoiceDataType == MainSaleInvoiceType.SOInvoice
group msi by new { dsi,msi.Date,msi.FinancialVoucher,msi.SaleOrderPrefix,msi.SaleOrderNumber,msi.SalesId,ca.CustomerName,ca.AccountCode,cg.Name }
into mainSaleInvoice
from dx in mainSaleInvoice.DefaultIfEmpty()
// orderby main.Id
select new
{
Date = mainSaleInvoice.Key.Date,
Voucher = mainSaleInvoice.Key.FinancialVoucher,
InvoiceAccount = mainSaleInvoice.Key.AccountCode,
CustomerName = mainSaleInvoice.Key.CustomerName,
CustomerGroup = mainSaleInvoice.Key.Name,
Invoice = mainSaleInvoice.Key.SaleOrderPrefix + mainSaleInvoice.Key.SaleOrderNumber,
PurchaseOrder = mainSaleInvoice.Key.SalesId,
SalesTax = "",
InvoiceAmount = mainSaleInvoice.Sum(x => (Double)(mainSaleInvoice.Key.Quantity * mainSaleInvoice.Key.UnitPrice))
}).ToList()
In linq, i need to get shortdatetimeString() and sum() of (unitprice* quantity) from child table DetialSaleInvoiceTbls
being new in query writing, I don't know where and what I'm doing wrong. Any suggestions would be much appreciated.
var list=from msi in db.MainSaleInvoiceTbls
join dsi in db.DetialSaleInvoiceTbls on msi.Id equals dsi.MainSaleInvoiceId
join ca in db.CustomerAccounts on msi.CustomerId equals ca.Id
join cg in db.MiscLists on ca.CustomerGroupId equals cg.Id into a
where msi.IsActive == true && msi.CompanyId == UniversalInfo.UserCompany.Id
&& msi.MainSaleInvoiceDataType == MainSaleInvoiceType.SOInvoice
from cg in a.DefaultIfEmpty()
select new
{mainSaleInvoice.Date,
mainSaleInvoice.FinancialVoucher,mainSaleInvoice.AccountCode,
mainSaleInvoice.CustomerName,mainSaleInvoice.Name,
mainSaleInvoice.SaleOrderPrefix, mainSaleInvoice.SaleOrderNumber,
mainSaleInvoice.SalesId, }).sum(x=>x. (mainSaleInvoice.Quantity *
mainSaleInvoice.UnitPrice)).groupby msi new
{msi.Date,msi.FinancialVoucher,msi.SaleOrderPrefix,msi.SaleOrderNumber,
msi.SalesId};
Date = mainSaleInvoice.Date;
Voucher = mainSaleInvoice.FinancialVoucher;
InvoiceAccount = mainSaleInvoice.AccountCode;
CustomerName = mainSaleInvoice.CustomerName;
CustomerGroup = mainSaleInvoice.Name;
Invoice = mainSaleInvoice.SaleOrderPrefix +
mainSaleInvoice.SaleOrderNumber;
PurchaseOrder = mainSaleInvoice.SalesId;
SalesTax = "";
InvoiceAmount =list;
This is my query:
var results = from table1 in dtSplitDates.AsEnumerable()
join table2 in dtSplitDates.AsEnumerable() on (int)table1["FID"] equals (int)table2["FID"] into lj
from r in lj.DefaultIfEmpty()
select dtSplitDates2.LoadDataRow(new object[]
{
r["FID"],
r["SLNO"],
r == null ? string.Empty : r["Dates"]
}, false);
Currently i am joining on Column FID - due to which i am getting 36 records (duplicates):
However in order to avoid duplicates i need to join also on SLNO column but i am unable to write that query - please help.
As per my understanding you want two join condition; Try this
var results = from table1 in dtSplitDates.AsEnumerable()
join table2 in dtSplitDates.AsEnumerable()
on new {id1 =(int)table1["FID"], SLno1= (int)table1["SLNO"]}
equals new {id2=(int)table2["FID"], SLno2=(int)table2["SLNO"]} into lj
from r in lj.DefaultIfEmpty()
select dtSplitDates2.LoadDataRow(new object[]
{
r["FID"],
r["SLNO"],
r == null ? string.Empty : r["Dates"]
}, false);
Try to implement with this example:
For Multiple Joins:
var result=(from com in db.Company.AsEnumerable()
join c in db.Country.AsEnumerable() on com.CountryID equals c.CountryID
join s in db.State.AsEnumerable() on com.StateID equals s.StateID
join ct in db.City.AsEnumerable() on com.CityID equals ct.CityID
orderby com.Name
select new CompanyModel()
{
CompanyID = com.CompanyID,
Name = com.Name,
AddressLine1 = com.AddressLine1,
CountryID = com.CountryID,
StateID = com.StateID,
CityID = com.CityID,
Country = c.CountryID,
State = s.StateID,
City = ct.CityID,
Pin = com.Pin,
Phone = com.Phone,
}).Distinct().ToList();
I have a search that looks for two things. Items and Contacts. They each have their own table with their own unique attributes. I am able to successfully search each independent of eachother and return the results to two list views. But is it ugly and paging has become a issue so I have to convert these two tables into a like result that I can display as a search result. These results have no relationship directly with eachother.
The group t3 by new is throwing me off. Do I have to group them to have it become a like result? The results currently get displayed in a ListView using for example <%#Eval("ItemName") %>
ItemContext db = new ItemContext(); //DB connection (Item,Contact)
var q = (from t1 in db.Item
join t2 in db.Categories on t1.CategoryID equals t2.CategoryID
join t7 in db.Divisions on t1.DivisionID equals t7.DivisionID
from t3 in db.Contacts
join t4 in db.Categories on t3.CategoryID equals t4.CategoryID
join t5 in db.Divisions on t3.DivisionID equals t5.DivisionID
join t6 in db.ContactTitle on t3.ContactTitlesID equals t6.ContactTitlesID
where
(DDLInt == 1 || t3.DivisionID == DDLInt) &&
//Contains
(
t3.ContactName.Contains(keyword) ||
t3.ContactEmail.Contains(keyword) ||
t3.ContactOPhone.Contains(keyword) ||
t3.ContactID.Equals(searchID)
)
group t3 by new
{
t3.ContactID,
t3.ContactName,
t3.ContactOPhone,
t3.ContactCell,
t3.ContactEmail,
t3.DivisionID,
t3.CategoryID,
t4.CategoryName,
t5.DivisionName,
t6.ContactTitlesName
}
into i
select new
{
i.Key.ContactID,
i.Key.ContactName,
i.Key.ContactOPhone,
i.Key.ContactEmail,
i.Key.ContactCell,
i.Key.CategoryName,
i.Key.DivisionName,
i.Key.CategoryID,
i.Key.DivisionID,
i.Key.ContactTitlesName
});
return q.ToList<dynamic>();
}
Use Union():
var contacts = from c in db.Contacts
select new {
Id = c.ContactID,
Name = c.ContactName,
Phone = c.ContactOPhone,
...
CategoryName = c.Category.CategoryName,
DivisionName = c.Division.DivisionName,
ContactTitlesName = c.ContactTitle.ContactTitlesName
}
var items = from t1 in db.Item
select new {
Id = t1.ItemID,
Name = t1.ItemName,
Phone = t1.??, // string.Empty?
... // more properties corresponding
// with the ones above
CategoryName = t1.Category.CategoryName,
DivisionName = t1.Division.DivisionName,
ContactTitlesName = string.Empty
}
var all = contacts.Union(items);