linq to entity framework: something like isnull - linq

I have:
a = b.Sum(...) + c.Sum(...)
where b,c are entities.
The problem is: when at least one of (b.Sum(...), c.Sum(...)) is null then a will be null. I'd like null be treated as 0. How would I do this?

At least in LINQ2SQL you can cast to int? manually and then handle the null case
a = ((int?)b.Sum(...) + c.Sum(...)).GetValueOrDefault();

maybe something like this
a = ( b.Sum(...) + c.Sum(...)) ?? 0;
now if the expression is null, a will be 0;

I think you could use null coelesce for this:
a = (b.Sum(..) + c.Sum(...)) ?? 0;
NOTE: unchecked syntax! not sure what your sums are doing!
Have a look at the following MSDN article: http://msdn.microsoft.com/en-us/library/ms173224.aspx

Related

Linq where clause invalid

var advocacy = (from c in svcContext.CreateQuery("lead")
join a in svcContext.CreateQuery("product")
on c["transactioncurrencyid"] equals a["transactioncurrencyid"]
where a["capg_billingtimeframe"].Equals(126350000)
select new
{
dues = c["capg_calculatedduesbilling"],
product = c["capg_primaryproduct"],
listprice = a["price"],
eligibility = c.FormattedValues["capg_eligibility"]
});
That is my linq query and it is giving me the error: Invalid 'where' condition. An entity member is invoking an invalid property or method.
I have looked online everywhere and done their suggestions. I am not using Xrm.cs because late binding can be faster. I have tried using the == operand and I have tried doing (int) and Convert.ToInt32(a["capg_billingtimeframe"]) and even converting everything to a string. I will say that a["capg_billingtimeframe"] I know is an object (that's why I did those conversions.
I'm guessing by that integer that capg_billingtimeframe is an optionset. If it is, you need to cast it like this:
where ((OptionSetValue)a["capg_billingtimeframe"]).Value == 126350000
I used early bound and for getting the local I wrote:
OptionSetValue branch = this.InputTargetEntity.Attributes.Contains("capg_calculatorutilized") ? (OptionSetValue)this.InputTargetEntity["capg_calculatorutilized"] : (OptionSetValue)this.TargetPreImage["capg_calculatorutilized"];
I then had to get the Optionsets.cs using crmsvcutil and writing:
if (branch.Value == (int)capg_calculatorrequired.SectionA)
Works like a charm.

Invoke an Expression in a Select statement - LINQ to Entity Framework

I'm trying to use an already existing Expression building class that I made when trying to do a select clause, but I'm not sure how to attach the expression to the expression tree for the Select, I tried doing the following:
var catalogs = matchingCatalogs.Select(c => new
{
c.CatalogID,
Name = EntitiesExpressionHelper.MakeTranslationExpression<Catalog>("Name", ApplicationContext.Instance.CurrentLanguageID).Compile().Invoke(c),
CategoryName = EntitiesExpressionHelper.MakeTranslationExpression<Category>("Name", ApplicationContext.Instance.CurrentLanguageID).Compile().Invoke(c.Category),
c.CategoryID,
c.StartDateUTC,
c.EndDateUTC
});
But I obviously get the error stating that the Entity Framework can't map Invoke to a SQL method. Is there a way to work around this?
FYI, EntitiesExpressionHelper.MakeTranslationExpression<T>(string name, int languageID) is equivalent to:
x => x.Translations.Count(t => t.LanguageID == languageID) == 0 ? x.Translations.Count() > 0 ? x.Translations.FirstOrDefault().Name : "" : x.Translations.FirstOrDefault(t => t.LanguageID == languageID).Name
EDIT: I realize that I need to use an ExpressionVisitor to accomplish this, but I'm not sure how to use an ExpressionVisitor to alter the MemberInitExpression, so if anyone knows how to accomplish this, let me know.
You need to capture the expressions in vars. You won't be able to use anonymous types. The general idea is that this works:
Expression<Func<Foo, Bar>> exp = GenExpression();
var q = matchingCatalogs.Select(exp);
But this will not:
var q = matchingCatalogs.Select(GenExpression());
The first happily passes the result of GenExpression to L2E. The second tries to pass GenExpression itself to L2E, rather than the result.
So you need a reference to a var of the same type as the expression. Those can't be implicitly typed, so you'll need a real type for your result type.

LINQ Dynamic Expression API, predicate with DBNull.Value comparison

I have an issue using the Dynamic Expression API. I cannot seem to compare a DataTable field against DBNull.Value. The API is supposed to be able to "support static field or static property access. Any public field or property can be accessed.". However given the following query:
var whatever = table1.AsEnumerable()
.Join(table2.AsEnumerable(),
(x) => x.Field<int>("Table1_ID"),
(y) => y.Field<int>("Table2_ID"),
(x, y) => new { x, y})
.AsQueryable()
.Where("x[\"NullableIntColumnName\"] == DBNull.Value");
I end up getting the error: "No property or field 'DBNull' exists in type '<>f__AnonymousType0`2'"
Anyone have ideas on how to get around this? I can't use Submission.Field("NullableIntColumnName") in the string passed to the Where method either, btw, or else I would be able to compare against null instead of DBNull.Value.
Well, I finally got it. cptScarlet almost had it.
var values = new object[] { DBNull.Value };
...
.Where("x[\"NullableIntColumnName\"] == #0", values);
or
.Where("x[\"NullableIntColumnName\"] == #0", DBNull.Value);
What happens when you replace your current .Where with something like
.Where(string.format("x[\"NullableIntColumnName\"] == {0}",DBNull.Value));
If you change x.Field<int>("Table1_ID") to x.Field<int?>("Table1_ID") then you'll get nullable integers instead of regular integers, and any DBNull values will be converted to simple C# null values. Based simply on your code snippet, I'm not even sure you'd need dynamic expressions - a simple .Where(foo => foo.x == null) ought to work.
In general, you can also try:
.Where("NullableColumnName.HasValue");
Sorry to non-answer with a USL but...
Have you looked in the source? There's not a lot of it. My guess is that DBNull is not in the list of registered root objects.
I dont have the source to hand right now, but it is also likely to tell you what any other constants one might compare against might be.
.Where(a => a.IntColName == null);
Edit:
Sorry, I did't see this dynamic requirement... Dynamic would be: (at least in Framework 4)
var intColName = "...";
.Where(string.Format("it.{0} is null", intColName));

nhibernate.linq simple (read dumb) question

I'm trying to wrap my head around linq -> nhib
I have a simple bit of sql that i'm trying to get working in nhibernate.linq
select * from
ColModel where ColModel.DataIndex
not in ('CostElement1', 'CostElement2', 'CostElement3')
and ColModel.ReportId = 1
The list of excluded DataIndex values comes in in the form of a List<string> called excludeNames
Here is what I have tried but it seems that it's not really feeling the love:
var s = base._sessionManager.OpenSession();
var query = from col in s.Linq<ColModel>()
where col.Report.Id == reportid &&
!(from c in s.Linq<ColModel>() select c.DataIndex).Contains(excludeNames)
select col;
return query.ToList();
the error:
The type arguments for method 'System.Linq.Enumerable.Contains<TSource>(System.Collections.Generic.IEnumerable<TSource>, TSource)' cannot be inferred from the usage. Try specifying the type arguments explicitly.
I'm pretty sure I'm borfing this from the offset so any pointers would be well appreciated :)
w://
Contains doesn't accept a list.
There are ways to work around this in LINQ, but I'm not sure which, if any, of those will work in NH Linq
I think you have your exclusion backwards.
s = base._sessionManager.OpenSession();
var query = from col in s.Linq<ColModel>()
where col.Report.Id == reportid &&
!excludeNames.Contains(col.DataIndex)
select col;
return query.ToList();
Collection.Contains(item) will produce the SQL item in (...collection...), adding the negation will get you what you want.

how do I pass null to int column in linq

How do we assign null value to int column in LINQ.
eg.
SQLDBDataContext sqlD = new SQLDBDataContext();
var result = from p in sqlD.loadsRadius(Convert.ToInt32(Request["radius"]), .....
here if Request["radius"] is null gives an error.
I could pass 0 via this but I need to change in many already existing procedures.
Thanks in advance.
Anil
You need to case the int to a null, eg:
var result = from p in sqlD.loadsRadius(string.IsNullOrEmpty(Request["radius"]) ? (int?)null : int.Parse(Request["radius"]);
If the exception is a FormatException, my guess is that the value returned by Request["radius"] is actually the string "null". If Request["radius"] actually returned null, Convert.ToInt32() would return zero. You may try using using int.TryParse() to avoid the exception.
as suggested by Codechef..
int radius = -1;
int.TryParse(Request["radius"],out radius)
if(radius > 0) // you can remove this clause if you don't want this
{
SQLDBDataContext sqlD = new SQLDBDataContext();
var result = from p in sqlD.loadsRadius(radius)
}
Look into nullable types: Here.
You could use ?? operator like this:
Convert.ToInt32(Request["radius"] ?? "0")
If Request["radius"] equals to null, it will return "0" instead.

Resources