How to use IList in joins with database - c#

ListMemSal = (from mem in ocontext.MEMBERs.Where(m => m.STATUS == 1 && m.SALARY_TYPE == 1)
join dept in ocontext.DEPARTMENTs on mem.DEPT_ID equals dept.DEP_ID
where dept.DEP_ID == DEP_ID
from sal in OListSalary.Where(m => m.MEMBER_ID == mem.ID && m.ISSUED_DATE.Month == _date.Month && m.ISSUED_DATE.Year == _date.Year).DefaultIfEmpty()
from jobTitle in ocontext.JOB_TITLE.Where(m => m.ID == mem.JOB_ID).DefaultIfEmpty()
I am getting an error on line 4 in my code from sal in OlistSalary.....
How to use ilist in joins?
Error Log :
Unable to create a constant value of type 'NameSpace.SALARY'. Only
primitive types or enumeration types are supported in this context.

Related

Simplify LINQ query

I have the following query:
db.ObjectTags.Where(c =>
c.TagID == tagID &&
(!db.DeletedObjects.Any(d=> d.ForObjectTypeID == c.ForObjectTypeID && d.ForObjectID == c.ForObjectID)
|| !db.DeletedObjects.SingleOrDefault(d => d.ForObjectTypeID == c.ForObjectTypeID && d.ForObjectID == c.ForObjectID).Deleted)
)
Its goal is to return objects that are not in a deleted state.
The table DeletedObjects has two states:
A record doesn't exist (not deleted)
A record exists with a deleted (bool) value
I need to query where either the record doesn't exist, or if it does the deleted value is false.
Is there any way to condense that statement eg with SingleOrDefault()?
You only need one !db.DeletedObjects.Any(...) and no SingleOrDefault
var q = db.ObjectTags
.Where(c=> c.TagID == tagID && !db.DeletedObjects
.Any(d => d.Deleted && d.ForObjectTypeID == c.ForObjectTypeID && d.ForObjectID == c.ForObjectID));
Can you please try this linq query
db.ObjectTags.Where(c =>
c.TagID == tagID &&
(db.DeletedObjects.Any(d=> d.ForObjectTypeID == c.ForObjectTypeID && d.ForObjectID == c.ForObjectID && !c.Deleted))
)
I believe you need to left join between ObjectTags and DeletedObjects. A LINQ query like this:
from objectTag in db.ObjectTags
from deletedObject in db.DeletedObjects
.Where(deletedObject => deletedObject.ForObjectTypeID == objectTag.ForObjectTypeID && deletedObject.ForObjectID == objectTag.ForObjectID)
.DefaultIfEmpty()
where deletedObject == null || !deletedObject.Deleted

Rewrite sql query to LINQ. Can't find an error

This is an SQL query:
SELECT Website,VendorID,Name,LinkProduct,
Link,Logo,Image,NameExtra as Industry,
(SELECT [Percent] FROM Web_Promotion
WHERE Web_Promotion.VendorID=Web_Vendor.VendorID)
AS PercentOff
FROM Web_Vendor WHERE Active='1' AND
(VendorID IN (Select VendorID FROM Web_Promotion
WHERE VendorID<>'' AND Static='True' AND [Percent] <> '0' AND
((Expires>=GETDATE()) OR (Expires IS NULL))) OR
VendorID IN (SELECT TOP 1 SC1 FROM NavItems
WHERE SC1=Web_Vendor.VendorID AND Promotion<>''
AND ((PromotionStart<=GETDATE() AND PromotionEnd>=GETDATE())
OR (PromotionStart<=GETDATE() AND PromotionEnd IS NULL))))
ORDER BY NameExtra,Sequence
I need to rewrite it to LINQ. So this is my LINQ:
return await _db.Web_Vendor.
Where(x => !(x.WebPromotion.VendorID == string.Empty || x.WebPromotion.VendorID == null)
&& x.WebPromotion.Static == true && x.WebPromotion.Percent != 0 &&
(x.WebPromotion.Expires >= DateTime.Now || x.WebPromotion.Expires == null)
||
(_db.NavItems.Where(y => x.WebPromotion.VendorID == y.SC1
&& !(y.Promotion == "" || y.Promotion == null)
&& (y.PromotionStart <= DateTime.Now) && (y.PromotionEnd >= DateTime.Now || y.PromotionEnd == null))
.Select(g => g.SC1).Take(1).Contains(x.WebPromotion.VendorID)))
.Include(x => x.WebPromotion).Where(x => x.Active == true).OrderBy(x => x.NameExtra)
.ThenBy(x => x.Sequence).ToListAsync();
I spent about three ours, but can't find an error. Original SQL query returns 16 rows, but my LINQ code returns only 13 of the. Unfortunately I have only one navigation property (Web_Vendor <-> Web_Promotion). I think that an error in the second part of my query:
||
(_db.NavItems.Where(y => x.WebPromotion.VendorID == y.SC1
&& !(y.Promotion == "" || y.Promotion == null)
&& (y.PromotionStart <= DateTime.Now) && (y.PromotionEnd >= DateTime.Now || y.PromotionEnd == null))
.Select(g => g.SC1).Take(1).Contains(x.WebPromotion.VendorID)))
Can any expert check my code and help me?
Correct data:
http://prntscr.com/9a5xwu
Linq data (not correct) contains the same data as correct instead of values where PercentOff is null.
The main problem is that LINQ generate inner join instead of left join in this place: http://prntscr.com/9a6stb
since you say that your linq data miss the case when PercentOff = null, i'd focus on that
I guess your "PercentOff" in Linq is Percent property, and i see that you have in your where: "x.WebPromotion.Percent != 0"
Is that a nullable value or you convert the null to the default property type, that is 0?
couldn't be that null is converted to 0 and then the query skip it?

LINQ error: The null value cannot be assigned to a member with type System.Int32 which is a non-nullable value type

I have following query:
var query = (from t1 in table1.Where(c => c.ServiceID == 2 && c.IsDeleted == 1)
from t2 in table2.Where(c => c.RelServiceBonID == t1.RelServiceBonID && c.IsDeleted == 1).DefaultIfEmpty()
from t3 in table3.Where(c => c.BonID == t1.BonID && c.UserID == 8 && c.IsDeleted == 1).DefaultIfEmpty()
from t4 in table4.Where(c => c.BonID == t1.BonID && c.IsDeleted == 1)
select new
{
t3.UserID, t2.SubServiceID,
});
query.Dump();
When I run, I got the following error:
The null value cannot be assigned to a member with type System.Int32 which is a non-nullable value type.
The UserID field is primary key and I can not set that as nullable!
How I can pass this error?
The UserID field is primary key and I can not set that as nullable
As hvd explained below, because you effectively have an outer join, UserID can still be null. Besides that, SubServiceID can also be null. Usually it helps to cast the culprit to a nullable type:
select new
{
UserID = (int?)t3.UserID,
SubServiceID = (int?)t2.SubServiceID
});

Linq to SQL - Exact Relational Division

The Linq-to-SQL query below, currently results in:
NotSupportedException: Local sequence cannot be used in LINQ to SQL implementations of query operators except the Contains operator.
Looks like the typical way to perform an exact relational division filter in linq is not available when using linq to SQL.
In the query below, we see the two attempts to use the Except clause to filter out any records that do not have IDs in the provided range.
Does anyone know what needs to be done besides changing to using a stored procedure or deferring the Expect filter to further filter on the returned list?
The section specifically is
&&
(additionalServiceIDs == null || additionalServiceIDs.Count == 0 ||
!(AdditionalServices.Where(ads => p.ReferenceNumber == ads.FK_Provider_ReferenceNumber).Select(ad => ad.FK_ServiceList_ID).Except(additionalServiceIDs).Any())
) // *ONLY* records that match the provided list of additionalServiceIDs, no more - no less (aka. Exact Relational Division)
&&
(additionalServiceIDs == null || additionalServiceIDs.Count == 0 ||
!(AdditionalNeeds.Where(adn => p.ReferenceNumber == adn.FK_Provider_ReferenceNumber).Select(an => an.FK_ServiceList_ID).Except(additionalNeedsIDs).Any())
) // *ONLY* records that match the provided list of additionalServiceIDs, no more - no less (aka. Exact Relational Division)
in :
List<int> additionalServiceIDs = new List<int>(){40,42};
List<int> establishmentIDs = new List<int>() {};
List<int> additionalNeedsIDs = new List<int>(){};
bool advertisedOnly = true;
bool Internal = true;
string providerTypeCode = "";
List<string> settingTowns = new List<string>() {};
var sqlResultsList = (from p in Providers
join po in ProviderOverviews on p.ReferenceNumber equals po.FK_Provider_ReferenceNumber into p_po
from p_po_LeftOuter in p_po.DefaultIfEmpty() // left outer join
join ad in AdditionalServices on p.ReferenceNumber equals ad.FK_Provider_ReferenceNumber into p_ad
from p_ad_LeftOuter in p_ad.DefaultIfEmpty() // left outer join
join sp in SchoolPickUps on p.ReferenceNumber equals sp.FK_Provider_ReferenceNumber into p_sp
from p_sp_LeftOuter in p_sp.DefaultIfEmpty() // left outer join
join an in AdditionalNeeds on p.ReferenceNumber equals an.FK_Provider_ReferenceNumber into p_an
from p_an_LeftOuter in p_an.DefaultIfEmpty() // left outer join
join il in Inspections on p.ReferenceNumber equals il.FK_Provider_ReferenceNumber into p_il
from p_il_LeftOuter in p_il.DefaultIfEmpty() // left outer join
join sl in SchoolLists on p_sp_LeftOuter.FK_SchoolList_SchoolID equals sl.SchoolID into sp_sl
from sp_sl_LeftOuter in sp_sl.DefaultIfEmpty() // left outer join
join nl in NeedLists on p_an_LeftOuter.FK_NeedsList_ID equals nl.ID into an_nl
from an_nl_LeftOuter in an_nl.DefaultIfEmpty() // left outer join
join svl in ServiceLists on p_ad_LeftOuter.FK_ServiceList_ID equals svl.ID into ad_svl
from ad_svl_LeftOuter in ad_svl.DefaultIfEmpty() // left outer join
join ptl in ProviderTypeLists on p.FK_ProviderTypeList_ID equals ptl.ID
where
(string.IsNullOrEmpty(providerTypeCode) || ptl.Code.ToLower() == providerTypeCode)
&&
p.Advertise == advertisedOnly
&&
(settingTowns == null || settingTowns.Count == 0 || settingTowns.Contains(p.SettingTown.ToLower())) // allow for no parameters being passed
&&
(establishmentIDs == null || establishmentIDs.Count == 0 || establishmentIDs.Contains(p_sp_LeftOuter.FK_SchoolList_SchoolID)) // allow for no parameters being passed
&&
(Internal == true || p.RegistrationStatus == "ACTV")// if internal = false then add filter .. RegistrationStatus = 'ACTV'
&&
(additionalServiceIDs == null || additionalServiceIDs.Count == 0 ||
!(AdditionalServices.Where(ads => p.ReferenceNumber == ads.FK_Provider_ReferenceNumber).Select(ad => ad.FK_ServiceList_ID).Except(additionalServiceIDs).Any())
) // *ONLY* records that match the provided list of additionalServiceIDs, no more - no less (aka. Exact Relational Division)
&&
(additionalNeedsIDs== null || additionalNeedsIDs.Count == 0 ||
!(AdditionalNeeds.Where(adn => p.ReferenceNumber == adn.FK_Provider_ReferenceNumber).Select(an => an.FK_NeedsList_ID).Except(additionalNeedsIDs).Any())
) // *ONLY* records that match the provided list of additionalServiceIDs, no more - no less (aka. Exact Relational Division)
select new // anonymous type
{
SettingTown = p.SettingTown,
ProviderTypeCode = ptl.Code,
ProviderName = p.ProviderName,
PublishedAddress = p_po_LeftOuter.PublishedAddressLocation,
Vacancies = p_po_LeftOuter.Vacancies,
VacancyMemo = p_po_LeftOuter.VacancyMemo,
PublishedPhone = p_po_LeftOuter.PublicPhone,
PublishedEmail = p_po_LeftOuter.PublicEmail,
Website = p_po_LeftOuter.Website,
AdditionalNeed = an_nl_LeftOuter.Description,
AdditionalNeedID = (int?)an_nl_LeftOuter.ID,
AdditionalService = ad_svl_LeftOuter.Description,
AdditionalServiceID = (int?)ad_svl_LeftOuter.ID,
CostPerDay = p_po_LeftOuter.CostPerDay,
CostPerHour = p_po_LeftOuter.CostPerHour,
CostPerSession = p_po_LeftOuter.CostPerSession,
Hours = p_po_LeftOuter.Hours,
InspectionOverallJudgement = p_il_LeftOuter.InspectionOVerallJudgement,
ReferenceNumber = p.ReferenceNumber,
ServiceDescription = p_po_LeftOuter.ServiceDescription,
SchoolPickUp = sp_sl_LeftOuter.SchoolName,
Under5 = p_po_LeftOuter.Under5,
Over5 = p_po_LeftOuter.Over5,
PublicTransport = p_po_LeftOuter.PublicTransport,
}).ToList();
The error message suggests that you can't use local sequence in LINQ to SQL except Contains() function. Based on that suggestion, try to avoid using .Except() and use .Contains() instead. You can replace this :
.Except(localCollection)
with this one :
.Where(!localCollection.Contains())
Example for your case :
(additionalServiceIDs == null || additionalServiceIDs.Count == 0 ||
!(AdditionalNeeds.Where(adn => p.ReferenceNumber == adn.FK_Provider_ReferenceNumber)
.Select(an => an.FK_ServiceList_ID)
.Where(fk => !additionalNeedsIDs.Contains(fk))
.Any())
) // *ONLY* records that match the provided list of additionalServiceIDs, no more - no less (aka. Exact Relational Division)
or simplified by merging both .Where()s :
(additionalServiceIDs == null || additionalServiceIDs.Count == 0 ||
!(AdditionalNeeds.Where(adn => p.ReferenceNumber == adn.FK_Provider_ReferenceNumber
&& !additionalNeedsIDs.Contains(adn.FK_ServiceList_ID))
.Select(an => an.FK_ServiceList_ID)
.Any())
) // *ONLY* records that match the provided list of additionalServiceIDs, no more - no less (aka. Exact Relational Division)
With help from #har07 I figured it out in entirety, the filter is thus.
&&
(additionalServiceIDs == null || additionalServiceIDs.Count == 0 ||
!(dbo.AdditionalServices.Where(ads => p_ad_LeftOuter.FK_Provider_ReferenceNumber == ads.FK_Provider_ReferenceNumber
&& !additionalServiceIDs.Contains(ads.FK_ServiceList_ID)
)
.Select(an => an.FK_ServiceList_ID)
.Any())
&&
p_ad_LeftOuter.FK_ServiceList_ID != null
&&
dbo.AdditionalServices.Where(ads => p_ad_LeftOuter.FK_Provider_ReferenceNumber == ads.FK_Provider_ReferenceNumber
&& additionalServiceIDs.Contains(ads.FK_ServiceList_ID))
.Select(an => an.FK_ServiceList_ID)
.Distinct()
.Count() == additionalServiceIDs.Count
)
&&
(additionalNeedsIDs == null || additionalNeedsIDs.Count == 0 ||
!(dbo.AdditionalNeeds.Where(ads => p_an_LeftOuter.FK_Provider_ReferenceNumber == ads.FK_Provider_ReferenceNumber
&& !additionalNeedsIDs.Contains(ads.FK_NeedsList_ID)
)
.Select(an => an.FK_NeedsList_ID)
.Any())
&&
p_an_LeftOuter.FK_NeedsList_ID != null
&&
dbo.AdditionalNeeds.Where(ads => p_an_LeftOuter.FK_Provider_ReferenceNumber == ads.FK_Provider_ReferenceNumber
&& additionalNeedsIDs.Contains(ads.FK_NeedsList_ID))
.Select(an => an.FK_NeedsList_ID)
.Distinct()
.Count() == additionalNeedsIDs.Count
)

How to do a left outer join with linq and many to many table?

When I tried to do a left outer join with MVC code first C#, I got this error:
The type of one of the expressions in the join clause is incorrect.
Type inference failed in the call to 'GroupJoin'.
I need help to understand why the join clause is wrong. Here is the code:
return (from t in context.Tenders
join c in context.Contacts on t.Contacts equals c.Tenders into leftOuter
from subpet in leftOuter.DefaultIfEmpty()
orderby t.id
where (c.Email == currentUserProfile.Email || c.UserProfileId == currentUserProfile.Id || t.UserProfileId == currentUserProfile.Id) && t.EndDate > now
&& t.IsClosed == false
&& t.IsCancel == false
select t).Union(
from t in context.Tenders
where t.EndDate > now
&& t.IsClosed == false
&& t.IsCancel == false
&& t.PrivacyLevelId == 1
select t).Count();
Fluent API:
// Many to many Tender => Contact
modelBuilder.Entity<Tender>()
.HasMany(c => c.Contacts)
.WithMany(t => t.Tenders)
.Map(m => m.MapLeftKey("TenderId")
.MapRightKey("ContactId")
.ToTable("ContactTender"));

Categories

Resources