hi i want to select multiple db from linq in same select statement
// gets specific information from Cabinet table
var chassi = (from a in db.Cabinets
from b in db.Commodities
from e in db.sArticleNumbers
where
kjopKollonne.Contains(e.ArtNum) &&
a.ArticleNumberID == e.ID &&
a.ArticleNumberID == b.ArticleNumberID
select new {
ArtNum = e.ArtNum,
Price = b.Price,
ModelName = a.ModelName,
}).ToList();
// gets specific information from cpu table
var cpu = (from a in db.cpu
from b in db.Commodities
from e in db.sArticleNumbers
where
kjopKollonne.Contains(e.ArtNum) &&
a.ArticleNumberID == e.ID &&
a.ArticleNumberID == b.ArticleNumberID
select new {
ArtNum = e.ArtNum,
Price = b.Price,
ModelName = a.ModelName,
}).ToList();
// Joins CPU and chassi information to one output
var query1 = (from a in chassi
from b in cpu
select new {
ArtNum = a.ArtNum and b.ArtNum, <-- problem
Price = a.Price,
ModelName = a.ModelName,
}).ToList();
If any one has a different approach to solving it, thanks for posting it.
It sounds like you're looking for the Union (removes duplicates) or Concat (keeps duplicates) methods.
Related
I have a long result set in linq which is put in ratestest, I am mapping the result to ChargeElementsNullable. The issue is this doesnt include a fee record which is
var fees = (from r in _dbContext.Rates
where r.RateTypeFK == RateType.Fee && (r.LocaleBW & localeid) > 0 && (r.PolicyBW & policy.BitWise) > 0 && r.RateExclude == 0
select r);
So I want to add fees to ratestest and I could do that mapping again so I can use the add method, but I dont want to do that long winded mapping just for one record.. I am trying to add it to ratestest directly instead.. but no joy... I tried using DefaultIfEmpty expecting a left join.. but fee still wasnt in there..
var ratestest = (from qi in quoteInputs
join r in _dbContext.Rates on qi.RatePK equals r.RatePK
join fee in fees on r.RatePK equals fee.RatePK into feecontainer
from fee in feecontainer.DefaultIfEmpty()
join c in _dbContext.Covers on r.CoverCalcFK equals c.CoverPK into covers
from c in covers.DefaultIfEmpty()
join rt in _dbContext.RateTypes on qi.RateTypeFK equals rt.RateTypePK
where rt.Ratable == 1 ||
rt.RateTypePK == RateType.PostCode ||
rt.RateTypePK == RateType.Fee// employersliab.Contains(r.InputFK)
select new ChargeElementsNullable
{
PolicyFK = quote.PolicyFK,
InputFK = r.InputFK,
LongRate = r.LongRate,
RateLabel = r.RateLabel,
CoverName = c.CoverName,
CoverFK = r.CoverCalcFK,
CoverBW = c.BitWise,
ListRatePK = r.ListRatePK,
RatePK = r.RatePK,
RateName = r.RateName,
Rate = r.Rate,
Threshold = r.Threshold,
Excess = r.Excess,
DivBy = r.DivBy,
DiscountFirstRate = r.DiscountFirstRate,
DiscountSubsequentRate = r.DiscountSubsequentRate,
HazardRating = r.HazardRating,
TableFirstColumn = r.TableFirstColumn,
TableChildren = r.TableChildren,
RateTypeFK = r.RateTypeFK,
PageNo = r.PageNo,
SumInsured = qi.SumInsured,
NoItems = qi.NoItems,
RateValue = qi.RateValue,
TriggerCode = rt.TriggerCode,
Territory = territory
}).ToList();
You have to create a model with two properties one for quoteInputs and another for fees. Then you just need to select both of them.
Eg:
class model1
{
public QuoteInputs quoteInputs {get;set;}
public Fees fees{get;set;}
}
Then you call use this model in the select clause and assign this model tables directly.
Now let's take your code and change select like this :
var ratestest = (from qi in quoteInputs
join r in _dbContext.Rates on qi.RatePK equals r.RatePK
join fee in fees on r.RatePK equals fee.RatePK into feecontainer
from fee in feecontainer.DefaultIfEmpty()
join c in _dbContext.Covers on r.CoverCalcFK equals c.CoverPK into covers
from c in covers.DefaultIfEmpty()
join rt in _dbContext.RateTypes on qi.RateTypeFK equals rt.RateTypePK
where rt.Ratable == 1 ||
rt.RateTypePK == RateType.PostCode ||
rt.RateTypePK == RateType.Fee// employersliab.Contains(r.InputFK)
select new model1{
quoteInputs = qi,
fees = fee
}).ToList();
As you mentioned in comments, you are seeking for Concat method (MSDN). This can be done like this:
var fees = from ...
select new ChargeElementsNullable {
Prop1 = (some value),
Prop2 = (other value)
}
var ratestest = from ...
select new ChargeElementsNullable {
Prop1 = (some value),
Prop2 = (other value)
}
var bothtogether = fees.Concat(ratestest);
Be sure, that you have all properties in exactly same order and all properties are in both selects. Otherwise Linq2Sql will fail when obtaining results. (I assume from your code that you are using it)
As #Cris correctly pointed out in comments, same order is not necessary.
I have three levels of master detail relation, One purchase can contain multiple challan, one challan can contain multiple items. each item has some quantity. I need to calculate total item quantity for every purchase. I've done that by the following, but it takes a lot of time just for a handful of data. I'm worried what will happen when the amount of data becomes large. Is there a way to do this in a single query using join or anything else? Thanks in advance.
var allData = (from p in _context.Prq_Purchase.AsEnumerable()
//where p.RecordStatus == "NCF"
from s in _context.Sys_Supplier
where s.SupplierID == p.SupplierID
from sa in _context.Sys_SupplierAddress
where sa.SupplierAddressID == p.SupplierAddressID
orderby p.PurchaseID descending
select new PurchaseReceive
{
PurchaseID = (p.PurchaseID).ToString(),
PurchaseNo= p.PurchaseNo,
SupplierID = (p.SupplierID).ToString(),
SupplierName = s.SupplierName,
Address = sa.Address,
SupplierAddressID = (p.SupplierAddressID).ToString(),
PurchaseCategory = p.PurchaseCategory,
PurchaseType = p.PurchaseType,
PurchaseYear = p.PurchaseYear,
PurchaseDate = (p.PurchaseDate).ToString("dd'/'MM'/'yyyy"),
RecordStatus= DalCommon.ReturnRecordStatus(p.RecordStatus)
}).ToList();
foreach(var Purchase in allData)
{
decimal TotalQty = 0;
var ChallanList= (from c in _context.Prq_PurchaseChallan.AsEnumerable()
where (c.PurchaseID).ToString()==Purchase.PurchaseID
select c).ToList();
foreach(var Challan in ChallanList)
{
var ItemList = (from i in _context.Prq_PurchaseChallanItem.AsEnumerable()
where i.ChallanID == Challan.ChallanID
select i).ToList();
foreach(var Item in ItemList )
{
TotalQty = TotalQty + Item.ReceiveQty;
}
}
Purchase.TotalItem = TotalQty;
}
I am new to Entity, and have a question regarding a LINQ statement.
Below appears my code, it appears with exception to "TotalFoults" field. He always gives 0.
Could anyone help me because all the results in the "TotalFoults" column have a value above zero.
Thank you very much.
var result = (from sr in db.StudentsResult
join F in db.Fouls on sr.Enrollment equals F.Enrollment into F_join
from F in F_join.DefaultIfEmpty()
join S in db.Students on sr.Enrollment equals S.Enrollment into A_join
from A in A_join.DefaultIfEmpty()
where
F.Day != null
group new { sr, s } by new
{
sr.Enrollment ,
sr.Name,
sr.Number,
sr.Classes,
s.Discount
} into g
orderby
g.Key.Classes,
g.Key.Number,
g.Key.Name
select new frequencyMod()
{
Enrollment = g.Key.Enrollment ,
StudentName = g.Key.Name,
StudentFile= g.Key.Number,
Classes = g.Key.Classes,
TotalFoults = (from m0 in db.Foults
where
m0.Enrollment == g.Key.Enrollment
group m0 by new
{
m0.Enrollment
} into a
select new
{
Total = a.Sum(p => p.Foults)
}).FirstOrDefault().Total
}).ToList();
I've made a query to get a list of articles, each bound to a "header",
so i retrieve the header plus the related articles and their properties.
The query works, however in its current style it is
Somewhat messy ( in my opinion)
The .ToList() takes way longer than i would expect.
Does anyone see any obvious reason for the speed-issue?
var offerheaders =
from o in dbcontext.F_CAB_OFFER_HEADERS
where
o.OFHD_FK_BUYER == userinfo.orgaTypeSequence
&& o.OFHD_VALID_FROM <= userinfo.selectedDate
&& o.OFHD_VALID_TO >= userinfo.selectedDate
&& o.OFHD_DELETED_YN == 0
&& o.OFHD_DELETED_BY_OWNER_YN == false
&& o.OFHD_OFFER_TYPE == userinfo.offerType
orderby o.OFHD_NO ascending
select o;
var offerlist =
from ofhd in offerheaders
select new {
ofhd = new {
OfferNo = ofhd.OFHD_NO,
OfferSequence = ofhd.OFHD_SEQUENCE,
ValidFrom = ofhd.OFHD_VALID_FROM,
ValidTo = ofhd.OFHD_VALID_TO,
OfferType = ofhd.OFHD_OFFER_TYPE,
Maingroup = new { cdmg_seq = ofhd.F_CAB_CD_MAIN_GROUP_TYPE.CDMG_SEQUENCE, Desc = ofhd.F_CAB_CD_MAIN_GROUP_TYPE.CDMG_DESC },
Supplier = new {
Name = ofhd.F_CAB_GROWER.F_CAB_ORGANISATION.ORGA_NAME,
Pic = ofhd.F_CAB_GROWER.F_CAB_ORGANISATION.ORGA_FK_PICTURE,
Seq = ofhd.F_CAB_GROWER.GROW_SEQUENCE
},
Caption = ofhd.OFHD_CAPTION,
Seperate = ofhd.OFHD_SHOW_SEPARATE_YN,
//ofdts = (from ofdt in dbcontext.F_CAB_OFFER_DETAILS.Where(x => x.OFDT_FK_OFFER_HEADER == ofhd.OFHD_SEQUENCE && x.OFDT_NUM_OF_ITEMS > 0 && x.OFDT_LATEST_DELIVERY_DATE_TIME > compareDateTime && x.OFDT_LATEST_ORDER_DATE_TIME > compareDateTime)
ofdts = from ofdt in dbcontext.F_CAB_OFFER_DETAILS
join props in dbcontext.F_CAB_CAB_PROP on ofdt.OFDT_FK_CAB_CODE equals props.PROP_FK_CABC_SEQ
join cabcode in dbcontext.F_CAB_CD_CAB_CODE on ofdt.OFDT_FK_CAB_CODE equals cabcode.CABC_SEQUENCE
join cabgroup in dbcontext.F_CAB_CD_CAB_GROUP on cabcode.CABC_FK_CAB_GROUP equals cabgroup.CDGR_SEQUENCE
join grouptype in dbcontext.F_CAB_CD_GROUP_TYPE on cabgroup.CDGR_FK_GROUP_TYPE equals grouptype.CDGT_SEQUENCE
join maingrouptype in dbcontext.F_CAB_CD_MAIN_GROUP_TYPE on grouptype.CDGT_FK_MAIN_GROUP equals maingrouptype.CDMG_SEQUENCE
join caca in dbcontext.F_CAB_CAB_CASK_MATRIX on ofdt.OFDT_FK_CACA_SEQ equals caca.CACA_SEQUENCE
join cask in dbcontext.F_CAB_CD_CASK on caca.CACA_FK_CASK equals cask.CDCA_SEQUENCE
join vbncode in dbcontext.F_CAB_CAB_VBN_MATRIX on cabcode.CABC_SEQUENCE equals vbncode.CVMA_FK_CAB_CODE
join grel in dbcontext.F_CAB_GENERAL_RELATIONS on ofdt.OFDT_FK_GREL_SEQ equals grel.GREL_SEQUENCE into greltable
from g_loj in greltable.DefaultIfEmpty()
where
ofdt.OFDT_FK_OFFER_HEADER == ofhd.OFHD_SEQUENCE
&& ofdt.OFDT_NUM_OF_ITEMS > 0
&& props.PROP_FK_CDLA_SEQ == userinfo.lang.CDLA_SEQUENCE
orderby props.PROP_CAB_DESC ascending
select new {
Desc = props.PROP_CAB_DESC,
Group = new { cdgr_seq = cabgroup.CDGR_SEQUENCE, Desc = cabgroup.CDGR_DESC },
Grouptype = new { grouptype.CDGT_SEQUENCE, Desc = grouptype.CDGT_DESC },
Properties = new CABProperties { props = props },
Price = ofdt.OFDT_ITEM_PRICE,
PIC_SEQ = ofdt.OFDT_FK_PICTURE ?? ((cabcode.CABC_FK_PICTURE ?? cabcode.CABC_SEQUENCE)),
PIC_URL = ofdt.OFDT_EXT_PICTURE_REF ?? "",
Seq = ofdt.OFDT_SEQUENCE,
Available = ofdt.OFDT_NUM_OF_ITEMS,
CabCode = ofdt.F_CAB_CD_CAB_CODE.CABC_CAB_CODE,
VBNCode = vbncode.CVMA_FK_VBN_CODE,
Remark = ofdt.OFDT_REMARK,
IsSpecial = ofdt.OFDT_SPECIAL_YN,
Arrived = inTransit ? ofdt.OFDT_ARRIVAL_DATE < DateTime.Now : true,
Cask = new CABCask { cask = cask, caca = caca },
Supplier = g_loj == null ? (ofdt.OFDT_SUPPLIER ?? "") : g_loj.GREL_NAME,
SupplierWeb = g_loj == null ? "" : g_loj.GREL_WEBSITE_URL,
SupplierLogo = g_loj == null ? ofhd.F_CAB_GROWER.F_CAB_ORGANISATION.ORGA_FK_PICTURE : g_loj.GREL_FK_PICT_SEQ,
SupplierSeq = g_loj == null ? -1 : g_loj.GREL_SEQUENCE,
}
}
};
userinfo.mainofferlist = offerlist.ToList();
As Daniel Kelly also mentioned the ToList function is where your query is executed, because these LinqToEntities queries are executed at the point where they are first enumerated, and ToList does that to be able to create a list.
Basically the reason why your querying takes so much time can be separated into two different reasons:
you are using too much projections and I thine (the parts with new {
})
your query has an incredible amount of join clauses
I would recommend to separate your query into subqueries, and run them separately like the first part in
...
select o
use
...
select o).ToList()
by breaking down the main query where you have a lot of subqueries it will be faster and much more readable, so you have less "messiness".
And last but not least you should create mapping for the anonymous objects, and use those classes other than projection that should speed up your query.
I have two queries that I would like to merge. This might be a left outer join, but it seems different.
The first query selects distinct stuff from a table:
var d = from d in db.Data
select (d.ID, d.Label, Value = 0).Distinct;
Lets suppose this returns the following:
{1,"Apple",0}
{2,"Banana",0}
{3,"Cabbage",0}
I then have another query that makes a different selection:
var s = from d in db.Data
where d.Label != "Apple"
select (d.ID, d.Label, d.Value);
This returns:
{2,"Banana",34}
{3,"Cabbage",17}
I then want a third query that joins the d and s together based upon their ID and their Label. I want the result to look like this:
{1,"Apple",0}
{2,"Banana",34}
{3,"Cabbage",17}
I'm basically just updating the numbers in the third query, but I have no idea how I should be doing this. It feels like it should be a simple join, but I just cannot get it to work.
This should work:
var query1 = from d in db.Data
select new { d.ID, d.Label, Value = 0 }.Distinct();
var query2 = from d in db.Data
where d.Label != "Apple"
select new { d.ID, d.Label, d.Value };
var result =
from d1 in query1
join d2 in query2 on new { d1.ID, d1.Label } equals new { d2.ID, d2.Label } into j
from d2 in j.DefaultIfEmpty()
select new
{
d1.ID,
d1.Label,
Value = d2 != null ? d2.Value : d1.Value
};
Note: are you sure you want to join on the ID and the label ? It seems rather strange to me... the label shouldn't be part of the key, so it should always be the same for a given ID
Here is one using method chain, which is my personal favorite.
var one = db.Data.Select(f => new {f.Id, f.Label, Value = 0});
var two = db.Data.Select(f => f).Where(f => f.Label != "Apple");
var three = one.Join(two, c => c.Id, p => p.Id, (c, p) => new {c.Id, c.Label, p.Value});
Could you just do
var s = from d in db.Data
select new
{
Id = d.ID,
Label = d.Label,
Value = (d.Label == "Apple" ? 0 : d.Value)
};