Unable to create a constant value of type 'System.DBNull'. Only primitive types or enumeration types are supported in this context - linq

I try to apply left outer join on the basis of two ids one in the primary key of one table while the foreign key of another table also nullable
var yarnPOFilter_Grid = (from yrq in _context.Yarn_Requisition_Details
//join ypo in
_context.Yarn_PurchaseOrder_Details on yrq.YarnRequsitionDetailID
equals
ypo.YarnRequsitionDetailID into t
join ypo in
_context.Yarn_PurchaseOrder_Details on yrq.YarnRequsitionDetailID
equals
DBNull.Value.Equals(ypo.YarnRequsitionDetailID) ? 0 :
ypo.YarnRequsitionDetailID into t
from rt in t.DefaultIfEmpty() //
DefaultIfEmpty preserves left-hand elements that have no matches on the
right side
select new
{
YarnRequsitionDetailID =
(rt.YarnRequsitionDetailID == null ? long.MinValue :
rt.YarnRequsitionDetailID),
yrq.YarnID,
yrq.Yarn.YarnName,
yrq.YarnFellowID,
yrq.Yarn_FellowCodes.YarnFellowCode,
yrq.QuantityRequired,
rt.QuantityOrdered,
QuantityBalance_Custom =
yrq.QuantityRequired - rt.QuantityOrdered
}).ToList();
return yarnPOFilter_Grid;
I get this error message when I deal with null in joining condition
Unable to create a constant value of type 'System.DBNull'. Only primitive types or enumeration types are supported in this context.

Execute ToList() First before Select as there is no sql equivalent to the conditions you added in the YarnRequsitionDetailID = (rt.YarnRequsitionDetailID == null ? long.MinValue : rt.YarnRequsitionDetailID)
so it will be
from rt in t.DefaultIfEmpty()).ToList().Select(c => new
{
YarnRequsitionDetailID =
(c.rt.YarnRequsitionDetailID == null ? long.MinValue :
c.rt.YarnRequsitionDetailID),
c.yrq.YarnID,
c.yrq.Yarn.YarnName,
c.yrq.YarnFellowID,
c.yrq.Yarn_FellowCodes.YarnFellowCode,
c.yrq.QuantityRequired,
c.rt.QuantityOrdered,
QuantityBalance_Custom =
c.yrq.QuantityRequired - c.rt.QuantityOrdered
}).ToList();
i hope this solved your previous problem

Related

Dynamic CRM :Contains<> is not working in CRM

My code is as below:
var conntionRecord1Id = (from connectionBase in orgServiceContext.CreateQuery("connection")
where connectionBase["record1roleid"] == null
select new { OpportunityId = connectionBase["record1id"] }).Distinct().ToList();
var query =
from opportunity in orgServiceContext.CreateQuery("opportunity")
orderby opportunity["createdon"] ascending
select new
{
Topic = opportunity.Attributes.Contains("name") == true ? opportunity["name"] : null,
OpportunityId = opportunity.Attributes.Contains("opportunityid") == true ? opportunity["opportunityid"] : null,
PostalCode = opportunity.Attributes.Contains("new_address_postalcode") == true ? opportunity["new_address_postalcode"] : null,
};
var result = (from f in query.ToList() where conntionRecord1Id.Contains(f.OpportunityId) select f).ToList();
But in above query where i am using Contains it giving count 0. even though I have common records in the list
The Contains Linq extension method does not know how to compare complex objects.
Comparing f.OpportunityId to a list of Guids instead of a list of an anonymous type will work:
var conntionRecord1Id = (from connectionBase in orgServiceContext
.CreateQuery("connection")
where connectionBase["record1roleid"] == null
select connectionBase.GetAttributeValue<Guid?>("record1id"))
.Distinct()
.ToList();
Implement IEqualityComparer in a custom comparer class to compare complex objects: https://stackoverflow.com/a/6694563/1817350
Keep in mind that calling .ToList() brings down all the records into memory and will cause performance problems with large amounts of records.

LINQ: Nullable object must have a value.

Let me preface this by saying I'm a novice with LINQ, and that this is code that I didn't originally write but am trying to fix. I've done a lot of research on this error, but I haven't found anything helpful yet. In fact, this error sort of makes my head spin. Anyway...
I have a LINQ query that is selecting some data from three SharePoint lists. Here it is:
private void loadPEGrid(int id)
{
dc = new SpEntityDataContext(SPContext.GetContext(this.Context).Web.Url);
EntityList<ProductDocumentMapItem> dMaps = dc.GetList<ProductDocumentMapItem>("Product Document Map");
object mappedItems = null;
mappedItems = from m in dMaps
join p in dc.PEProducts on m.ProductID.Value equals p.Id.Value
join d in dc.ProductDocuments on m.DocID.Value equals d.Id.Value
where m.ProductID.Value == id && m.ProductType == "PE"
select new {
p.Grade,
d.Path,
d.DocumentType,
d.Title,
d.Name,
Language = d.Language.Title,
m.Id,
DocId = m.DocID };
GridViewProducts.KeyFieldName = "Id";
GridViewProducts.DataSource = mappedItems;
GridViewProducts.DataBind();
}
The following fields are nullable:
m.ProductID
m.DocID
d.DocumentType
m.Id
When I debug, none of this throws an error, but when the page loads it does:
System.InvalidOperationException: Nullable object must have a value
Does this mean that one of the fields I'm selecting is null, or one of the join fields? Having checked the data, I don't think this is the case. Let me know if you need any more info from me.
System.InvalidOperationException: Nullable object must have a value
This exception is thrown when you are trying to get Value property of nullable type. So, that means one or more of following is true:
At least one of objects in dMaps has property ProductID equal to null
At least one of objects in dMaps has property DocID equal to null
At least one of objects in dc.PEProducts has property Id equal to null
At least one of objects in dc.ProductDocuments has property Id equal to null
Exception raised not by query

LINQ NullReferenceException on DefaultIfEmpty

I'm looking for a solution to the problem of having the DefaultIfEmpty() extension method not picking up null values when used in a LINQ outer join.
Code as follows:
var SummaryLossesWithNets = (from g in SummaryLosses
join n in nets
on g.Year equals n.Year into grouping
from x in grouping.DefaultIfEmpty()
select new
{
Year = g.Year,
OEPGR = g.OccuranceLoss,
AEPGR = g.AggregateLoss,
OEPNET = ((x.OEPRecovery == null) ? 0 : x.OEPRecovery),
AEPNET = ((x.AEPRecovery == null) ? 0 : x.AEPRecovery),
});
In the List SummaryLosses there are many years worth of data I wish to join to the table 'nets' which contains a sub-portion of the years. The exception is thrown on x being a null value, I am assuming because the years in SummaryLosses not matched by years in nets creates null values in the grouping list.
How should one go about checking for the null value here? As you can see I've attempted to check for null on the properties of x, but since x is null this doesn't work.
Kind regards
Richard
Simply check whether x is null instead:
OEPNET = x == null ? 0 : x.OEPRecovery,
AEPNET = x == null ? 0 : x.AEPRecovery
Or if x.OEPRecovery and x.AEPRecovery are nullable properties too, use:
OEPNET = x == null ? 0 : (x.OEPRecovery ?? 0),
AEPNET = x == null ? 0 : (x.AEPRecovery ?? 0)
If you have many join statements
check check all joined tables and ensure that the foreign key you are using
(in comparing or lets say Interested in) is not null

Distinct works on IQueryable but not List<T>?? Why?

First Table is the View and Second is the result I want
This below query works fine
List<BTWStudents> students = (from V in db.vwStudentCoursesSD
where classIds.Contains(V.Class.Value)
select new BTWStudents
{
StudentId = V.StudentId
Amount= V.PaymentMethod == "Cashier Check" ? V.Amount: "0.00"
}).Distinct().ToList();
But I changed it to List to add string formatting(see below)
List<BTWStudents> students = (from V in db.vwStudentCoursesSD
where classIds.Contains(V.Class.Value)
select new {V}).ToList().Select(x => new BTWStudents
{
StudentId = V.StudentId
Amount= V.PaymentMethod == "Cashier Check" ? String.Format("{0:c}",V.Amount): "0.00"
}).Distinct().ToList();
With this Second Query I get this
Why is distinct not working in the second query?
When working with objects (in your case a wrapped anonymous type because you are using Select new {V} rather than just Select V), Distinct calls the object.Equals when doing the comparison. Internally, this checks the object's hash code. You'll find in this case, the hash code of the two objects is different even though the fields contain the same values. To fix this, you will need to override Equals on the object type or pass a custom IEqualityComparer implementation into the Distinct overload. You should be able to find a number of examples online searching for "Distinct IEqualityComparer".
Try this (moved your distinct to the first query and corrected your bugged if/then/else):
List<BTWStudents> students = (from V in db.vwStudentCoursesSD
where classIds.Contains(V.Class.Value)
select new {V}).Distinct().ToList().Select(x => new BTWStudents
{
classId = V.Class.HasValue ? V.Class.Value : 0,
studentName = V.StudentName,
paymentAmount = V.PaymentMethod == "Cashier Check" ? String.Format("{0:c}",x.V.AmountOwed): "0.00"
}).ToList();
You can get around using Distinct all together if you Group by StudentID
var studentsGroupedByPayment =
(from V in db.vwStudentCoursesSD
where classIds.Contains(V.Class.Value)
group V by V.StudentId into groupedV
select new
{
StudentID = groupedV.Key,
Amount = string.Format("{0:C}",
groupedV.First().PaymentMethod == "Cashier Check" ?
groupedV.First().Amount : 0.0)
}
).ToList();

Error within Where statement in LINQ

For some reason in my where it says that "firstname" does not exist in the Opportunity Entity. But it is set for the SystemUser Entity. Any idea why it is getting confused? Thanks!
var linqQuery = (from r in gServiceContext.CreateQuery("opportunity")
join c in gServiceContext.CreateQuery("account") on ((EntityReference)r["accountid"]).Id equals c["accountid"]
join u in gServiceContext.CreateQuery("systemuser") on ((EntityReference)r["ownerid"]).Id equals u["systemuserid"]
where r["new_leadstatus"].Equals("100000004") && u["lastname"].Equals(rsmLastName) && u["firstname"].Equals(rsmFirstName)
select new
{
AccountId = !r.Contains("accountid") ? string.Empty : r["accountid"],
Account = !r.Contains("name") ? string.Empty : r["name"]
});
Make sure you put each where clause in its own line per Microsoft guidelines.
The where clause applies a filter to the results, often using a
Boolean expression. The filter specifies which elements to exclude
from the source sequence. Each where clause can only contain
conditions against a single entity type. A composite condition
involving multiple entities is not valid. Instead, each entity should
be filtered in separate where clauses.
var linqQuery = from r in gServiceContext.CreateQuery("opportunity")
join c in gServiceContext.CreateQuery("account") on ((EntityReference)r["accountid"]).Id equals c["accountid"]
join u in gServiceContext.CreateQuery("systemuser") on ((EntityReference)r["ownerid"]).Id equals u["systemuserid"]
where r["new_leadstatus"].Equals("100000004")
where u["lastname"].Equals(rsmLastName) && u["firstname"].Equals(rsmFirstName)
select new
{
AccountId = !r.Contains("accountid") ? string.Empty : r["accountid"],
Account = !r.Contains("name") ? string.Empty : r["name"]
};
You define your reference to the Opportunity entity as 'r' but are trying to read firstname from 'u'
from r in gServiceContext.CreateQuery("opportunity")
u["firstname"]
Change the end of your where to
r["firstname"].Equals(rsmFirstName)

Resources