Dynamic Where in Linq to SQL - vb.net

How would I get something like this to work so that I can dynamically alter the where-clause in this linq to sql query?
Dim AccountID = 1234
Dim AccountList
Select Case Types
Case 1
AccountList = (from a in dc.Accounts where a.ID = AccountID)
Case 2
AccountList = (from a in dc.Accounts where a.ID = AccountID And a.ParentID = AccountID)
Case Else
AccountList = (from a in dc.Accounts)
End Select
Return From p in dc.Products where AccountList.Contains(p.Order.Transaction.AccountID)
With the above code I get this error:
Late binding operations cannot be converted to an expression tree

It sounds like you've either not got Option Strict on. Put it on, and specify the type of AccountList as IQueryable(Of Account). Then you won't be using late binding, and all should be well.

Related

Linq, SQL, and ISNULL

I'm trying to figure Linq out. I'm having very little success and most of the articles are for C# which isn't helping.
I'm trying to make the following work;
Dim query = From r In db.eq_list
Join s In db.interview_main On r.CLIENTCODE Equals s.CLIENTCODE And r.CONTROL Equals s.CONTROL
Select New With {r.UserName, r.CONTROL, r.CLIENTCODE, r.CLIENTLOCATION, r.IDATETIME, r.FIRSTNAME,
r.LASTNAME, If(String.IsNullOrEmpty(s.Code), 0, s.Code)}
dgvOnHold.DataSource = query.ToList
The problem is the IF part. This part can be NULL in the database, but I want it returned as 0 if NULL. I'm putting this into a read-only Datagridview. The original SQL is as follows;
SELECT r.ID,r.UserName,r.CONTROL,r.CLIENTCODE,r.CLIENTLOCATION,r.IDATETIME,r.FIRSTNAME,r.LASTNAME,ISNULL(s.CODE,0) AS CODE
FROM system.eq_list AS r
LEFT JOIN interview.main AS s ON r.CLIENTCODE = s.CLIENTCODE AND r.CONTROL = s.CONTROL;
Can't check this at the moment but how about?
Dim query = From r In db.eq_list
Join s In db.interview_main On r.CLIENTCODE Equals s.CLIENTCODE And r.CONTROL Equals s.CONTROL
Select New With {r.UserName, r.CONTROL, r.CLIENTCODE, r.CLIENTLOCATION, r.IDATETIME, r.FIRSTNAME,
r.LASTNAME, If(s.Code is Nothing, 0, s.Code)}
dgvOnHold.DataSource = query.ToList

LinQ: join on nullable property with value null

I have a list of objects, with a property customerId which is a nullable System.Guid property.
I also have a list of id's of type System.Guid, I also added a Guid.Empty value to this list.
I try to do a join on both, but the objects with empty guids aren't returned.
Dim dos = (From d In documents Join c In allowedCustomers On c Equals If(d.CustomerGuid = Nothing, System.Guid.Empty, d.CustomerGuid) Select d).Skip(10 * (pageNr - 1)).Take(10).ToList
What is wrong? Is there another way to do this in a better way?
You are using d.CustomerGuid = Nothing but you have to use d.CustomerGuid Is Nothing.
Try this approach which uses the VB.NET's null-coalescing operator.
Dim query = From doc In documents
Join custID In allowedCustomers
On If(doc.CustomerGuid, Guid.Empty) Equals custID
Skip 10 * (pageNr - 1)
Take 10
Select doc
Dim docList = query.ToList()
Note that you can increase readability with multiple lines, also, VB.NET's query syntax is powerful than C#, so you can use Skip and Take in the query.

Where clause in LINQ query is not recognized in vb.net?

The entity field is not recognized in the following Where clause. Is the VB wrong?
Dim projects = context.projects
.OrderBy(Function(x) x.name)
.Select(Function(x) {x.id, x.name})
.Where(Function(x) x.id <> sourceid)
If I take the Where off, it works fine. Also, if I flip the Where and the OrderBy, Where is fine, but now OrderBy fails.
Try this:
Dim projects = context.projects
.OrderBy(Function(x) x.name)
.Select(Function(x) New With {x.id, x.name})
.Where(Function(x) x.id <> sourceid)
The New With keyword should create an IEnumerable of anonymous type. You can then work with the id property in the Where clause without having to change the order of your operations.
There is nothing stopping you from doing the operations OrderBy, Select, Where in that order. The above code will certainly compile and run. However, logically you need to do the Where before Select, since the former is a filtering operation, while the latter is a projection.
Can you please try with the below code snippet.
Dim projects = context.projects.Where(Function(x) x.id <> sourceid).OrderBy(Function(x) x.name).Select(Function(x) {x.id, x.name})
This {x.id, x.name} is most likely an array of object (assuming id is integer and name is string, VB would infer Object). It is not an instance of a class with properties of id and name. #shree.pat18 explained how it can be adjusted to return what you want, but I would suggest using query syntax for clarity, and also putting your where clause before Select (should be slightly faster, because it does not create anonymous objects from the values you don't need included in results):
Dim projects = From p In context.projects
OrderBy p.name
Where p.Id <> sourceid
Select Id = p.Id, Name = p.Name

conversion C# to vb.net issue

I am trying to convert C# to vb.net in WCF, the given below is the line of code
var user = from u in users
where u.Key == Id
select u.Value;
On using the conversion tool I get the following result
Dim user = _Where u.Key = Id
but simultaneously I get an error 'End of statement expected'
What am I doing wrong? Can anybody help me out on this?
It's about the same using query syntax really:
Dim users = From user In users
Where user.Key = Id
Select user
The Select is degenerate and if you would prefer, you could use method syntax instead:
users.Where(Function(user) user.Key = ID)
Try this:
Dim user = From u in users
Where u.Key = Id
Select u.Value
Dim user = From u in users Where u.Key = id
Select u.Value
You could also use a lambda.
Dim user = users.FirstOrDefault(Function(u)u.Key = id)
In the Lambda I used FirstOrDefault as you are using a key. This mean when the first record has been found, no extra time is wasted on searching the rest of the collection. it also means user will be null if nothing is found. If it was just a Where clause you would potentially end up with an empty collection.

LINQ To Entities .Any() results in null reference exception

I have a simple query as below:
Dim sizings = From a In db.Sizings
Where a.Customer.ID = customer.ID
Select a
If sizings.Any Then
.....
The sizings.Any line is throwing a null reference exception. I thought I was meant to use .Any to determine if there were any rows returned?
isnothing(sizings) returns false.
Any ideas?
Edit - Resolution:
Don't use null objects in the LINQ Query!
Try checking that Customer isn't null before comparing its ID.
Dim sizings = From a In db.Sizings
Where a.Customer IsNot Nothing And a.Customer.ID = customer.ID
Select a
If sizings.Any() Then
'
End If
What about using sizings.Count() > 0