How to check "Is Nothing" in Linq dynamic query - linq

I'm trying to check a very basic expression with Linq dynamic queries.
Although this woks perfectly with regular Linq.
Dim xxx = From x In db.Users Where x.AgentID Is Nothing Select x.FirstName, x.LastName
it seems not to work with dynamic queries:
Dim xx = db.Users.Where("AgentID Is Nothing").ToList
I get this error:
Boolean expression expected
What am I doing wrong ?

You must have a Boolean expression not a string to get the result like:
Dim xx = db.Users.Where(u=>u.AgentID==null).ToList()

I found following solution :
"AgentID.HasValue = False"

Related

If Statement inside LINQ Select Query

I has a table call Staff and has two field call StaffStatus and ParentStatus. I would like to display the Status as "Available" when StaffStatus AND ParentStatus are both "Available" and display the Status as "Unavailable" when either StaffStaus OR ParentStatus is "Unavailable".
Friend Function getAllUser(strInput As String) As IQueryable
getAllUser = From userDB In db.Staffs
Select Status = userDB.UserStatus.Equals("Available") And userDB.ParentStatus.Equals("Available") ? "Available" : (userDB.UserStatus.Equals("Unavailable") Or userDB.ParentStatus.Equals("Unavailable") ? "Unavailable")
End Function
But the code editor show : The character "?" cannot be used here and the Syntax error of first "(" at ": (userDB.UserStatus.Equals("Unavailable")". Any error with my code?
Simply: There is no ternary operator (as you use it) in VB.NET
Take a look at here: Is there a conditional ternary operator in VB.NET?
You have to use a Dim foo as String = If(bar = uz, cat, dog) construct
Edit:
Try this
Dim getAllUser = From userDb In db.Staffs
Select New Staff() With
{
.UserStatus = If(userDb.UserStatus.Equals("Available") And userDb.ParentStatus.Equals("Available"), "Available", If(userDb.UserStatus.Equals("Unavailable") Or userDb.ParentStatus.Equals("Unavailable"), "Unavailable", "SomeOtherValue"))
}

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.

Linq to datasets - getting specific column value in C#

i'm trying to get an error description according to error Id:
String errorDesc = from resultCodesTableRow in resultCodesDT.AsEnumerable()
where resultCodesTableRow.Field<int>("Error_Code_Column_Name") == errorCode
select resultCodesTableRow.Field<string>("Error_Desc_Column_Name").ToString();
why do i get the error:
"Cannot implicitly convert type 'System.Data.EnumerableRowCollection' to 'string'" ?
how does the query supposed to look ?
Change
resultCodesDT.AsEnumerable() to resultCodesDT.rows
Does this work:
where (int)resultCodesTableRow.GetItem("Error_Code_Column_Name") == errorCode
select resultCodesTableRow.GetItem("Error_Desc_Column_Name")
I am not pretty sure what the actual LINQ query is returning most probably by seeing it and as you said you are getting error it might be returning a Collection so in order to avoid use first or last method to the query ie
String errorDesc = from resultCodesTableRow in resultCodesDT.AsEnumerable()
where resultCodesTableRow.Field("Error_Code_Column_Name") == errorCode
select resultCodesTableRow.Field("Error_Desc_Column_Name").First().ToString();
the Select function in your statement will return an IEnumerable.
instead you need to use something like
String errorDesc = (from resultCodesTableRow in resultCodesDT.AsEnumerable()
where resultCodesTableRow.Field<int>("Error_Code_Column_Name") == errorCode
select resultCodesTableRow.Field<string>("Error_Desc_Column_Name").ToString()).First();
or maybe this would work but is untested
String errorDesc = resultCodesDT.Where(X=> x.Error_Code_Column_Name==errorCode)
.Select(s=>s.Error_Desc_Column_Name.toString()).First();

Linq Compiled Queries and int[] as parameter

I'm using the following LINQ to SQL compiled query.
private static Func<MyDataContext, int[], int> MainSearchQuery =
CompiledQuery.Compile((MyDataContext db, int[] online ) =>
(from u in db.Users where online.Contains(u.username)
select u));
I know it is not possible to use sequence input paramter for a compiled query and im getting “Parameters cannot be sequences” error when running it.
On another post here related , I saw that there is some solution but I couldn't understand it.
Does anyone know to use complied query with array as input paramter?
Please post example if you do.
Like the post that you referenced, it's not really possible out of the box. The post also references creating your own query provider, but it's a bit of overhead and complexity that you probably don't need.
You have a few options here:
Don't use a compiled query. Rather, have a method which will create a where clause from each item in the array resulting in something like this (psuedo-code):
where
online[0] == u.username ||
online[1] == u.username ||
...
online[n] == u.username
Note that you would have to use expression here to create each OR clause.
If you are using SQL Server 2008, create a scalar valued function which will take a table-valued parameter and a value to compare againt. It will return a bit (to indicate if the item is in the values in the table). Then expose that function through LINQ-to-SQL on your data context. From there, you should be able to create a CompiledQuery for that. Note that in this case, you should take an IEnumerable<string> (assuming username is of type string) instead of an array, just because you might have more than one way of representing a sequence of strings, and to SQL server for this operation, it won't matter what the order is.
One solution that I have found myself doing (for MS SQL 2005/2008). And I'm not sure if it is appropriate in all scenarios is to just write dynamic sql and execute it against the datacontext using the ExecuteQuery method.
For example, if I have an unbounded list that I am trying to pass to a query to do a contains...
' Mock a list of values
Dim ids as New List(of Integer)
ids.Add(1)
ids.Add(2)
' ....
ids.Add(1234)
Dim indivs = (From c In context.Individuals _
Where ids.Contains(c.Id) _
Select c).ToList
I would modify this query to create a SQL string to execute against the database directly like so...
Dim str As New Text.StringBuilder("")
Dim declareStmt as string = "declare #ids table (indivId int) " & vbcrlf)
For i As Integer = 0 To ids.Count - 1
str.Append("select " & ids(i).ToString() & " & vbcrlf)
If i < ids.Count Then
str.Append("union " & vbcrlf)
End If
Next
Dim selStatement As String = "select * From " & context.Mapping.GetTable(GetType(Individuals)).TableName & _
" indiv " & vbcrlf & _
" inner join #ids ids on indiv.id = ids.id"
Dim query = declareStmt & str.ToString & selStatement
Dim result = context.ExecuteQuery(of Individual)(query).ToList
So barring any syntax errors or bugs that I coded (the above is more or less psuedo code and not tested), the above will generate a table variable in SQL and execute an inner join against the desired table (Individuals in this example) and avoid the use of a "IN" statement.
Hope that helps someone out!

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.

Resources