Statement in linq lambda expression - vb.net

I have a list of it, that is my SelectedValue from some ComboBox.
Dim AppsInt = MyApps.CheckedItems.Select(Function(x) Convert.ToInt32(x.Value)).ToList()
And i have this object that is a list( of t)
Dim myObj = New List( Of Item )
Dim FooItem = New item ( 42 )
What I want is to get my list of Int into my object. With Something that would look like this in C#:
AppsInt.foreach( x => myObj .add(new Item(x) ) ) ;
What i have done so far is sending me a "do not produce a result" error:
AppsInt.ForEach( Function(it) myObj.Add(New Item(it)) )
How can i do it ? How to make this linq lambda work?

you should change function(it) to sub(it) .
Or:
Dim myObj = AppsInt.Select( Function(it) New Item(it)).ToArray()

Lambda expression inside you ForEach expression does not returns any result (and compiler said it to you). It means that you have two ways to solve it:
Add return statement into your lamda expression that will return anything:
AppsInt.ForEach(Function(it)
myObj.Add(New Item(it))
Return 1 ' it's not matter what you will return here.
End Function)
Change Function(it) to Sub(it). Sub is not obliged to return any value.
Second option is more preferable.

Related

How to not add to the list, when the return of a LINQ IEnumerable is empty?

I do have the following VB.NET code:
Dim list = directoryQuery.Select(
Function(d) New With {
.dir = d.FullName,
.acl = GetFileSystemAccessRule(d).Select(
Function(a) New With {.if = a.Reference.ToString()}
)
}
)
End Sub
Sometimes the return of GetFileSystemAccessRule(d).Select is Return Enumerable.Empty(Of FileSystemAccessRule)(). In that case, I would like to neither add .directory nor .acl to that list. I want to skip it.
So I tought about the options to remove afterwards the empty items.
//tried but failed:
list = list.Where(Function(a) a.acl IsNot Enumerable.Empty(list)).ToList()
//tried but failed:
list = list.Where(Function(a) a.acl IsNot Nothing).ToList()
But unfortunately all of them failed. What do I wrong?
I think this would be the way to go:
list = list.Where(Function(a) a.acl.Any())
or something closely resembling that (I'm not very well versed in VB.NET syntax).

Calling a function within Entity Framework Select

A property from my object (oJobs) is as follows:
Private _brandlist As List(Of DAL.Brand)
Public Property PostBrandList() As List(Of DAL.Brand)
Get
Return _brandlist
End Get
Set(ByVal value As List(Of DAL.Brand))
_brandlist = value
End Set
End Property
In the database, the brand list is stored as a string separated by comma e.g. the column 'brands' can be a string '3,45,2' where each number represents an id of a brand stored in another table.
my select query is as below:
Dim jobposts As List(Of oJobs) = From j In db.JobPostings
Select New oJobs With { 'hiding all others for code brevity
.PostBrandList = 'problem is here'
}
Since j.BrandList will return a string, I will need to split that string and for each number, run another query to finally return and assign a List(Of DAL.Brand) into .PostBrandList
For those who might ask "what have you tried?",
I have run the query, then did a for each to add the list of brands later - succeeded but not optimal
Coded a function that takes the list as a parameter and returns a separate list of objects - very silly.
Also, I am not allowed to normalize the DB :(
Not tested and might need some tweaking but heres one idea. you will also need to change your property to an IEnumerable rather than List. Because the second linq query is embedded within the first, I believe it should execute it all as one query, but you should check it to make sure.
Dim jobposts As List(Of oJobs) = From j In db.JobPostings
Select New oJobs With { 'hiding all others for code brevity
.PostBrandList = From b In db.Brands Where j.Brands = b.ID Or j.Brands.StartsWith(b.ID & ",") Or j.Brands.EndsWith("," & b.ID) Or j.Brands.Contains("," & b.ID & ",") Select b
}
In c# you can use
.Select(x=>new {x.BrandList})
.ToList() //Materialize first before calling function
.Select(x=> new oJobs{
PostBrandList =
db.Brands.Where(z=>
x.BrandList
.Split(',')
.Select(y=>int.Parse(y.Trim()))
.Contains(z.Id))
.ToList()
});
Note that you must materialize entity first before calling String.Split
I don't know how to translate that to VB.NET.
Of course it will cause SELECT n+1 problem because you can't use join.
If you can't normalize table, my other suggestion is to create indexed view (sql server), so you can use join and improve performance.
Indexed view https://msdn.microsoft.com/en-us/library/ms191432.aspx
You could try it with the Let statement:
Dim jobposts As List(Of oJobs) = From j In db.JobPostings
/* li in the LINQ Statement represents one string value from the BrandList list */
Let postBrandElemsList = j.BrandList.Split(',').Select(Function(li) New DAL.Brand With { ... /* Field initializatione of the Class DAL.Brand here */ }
Select New oJobs With
{
.PostBrandList = postBrandElemsList
}
I'm sorry for the probably bad VB.NET syntax, you should check this when implementing it in your code.
Maybe you would just want to use the Split function on the column brands into an array and iterate through the result, using the Find function to retrieve the brand objects?

linq select C# to vb.net

I need the following LINQ statement corverted to VB.net. but
collection.Select(c => {c.PropertyToSet = value; return c;});
Here's what I have, but I want to do the 'return' instruction.
collection.Select(function (c) c.PropertyToSet = value ***return c*** )
Any ideas on how to get that converted?
Thanks a lot!
If you want to change all properties of an object in the collection, Select method is not appropriated method to do this.
Since the collection object is a List(Of T), you could try this with ForEach method:
collection.ForEach(Sub(c) c.PropertyToSet = value)
With Select method, you could try this:
collection = collection.Select(Sub(c) c.PropertyToSet = value)
Alternatively, you could use the language structure For Each for it:
For Each c as YourType In collection
c.PropertyToSet = value
Next
I think this is the way, did not test it but it should work
Collection.Select(Function(c)
c.PropertyToSet = value
Return c
End Function)
If you are looking to get a filtered IList back, try this:
collection.Where(Function(c) c.PropertyToSet = Value).ToList

LINQ expression to expression tree via API in VB

I have a relatively simple LINQ expression which I need to convert into VB expression tree syntax. This is likely an easy task for folks that are familiar, but I am new to the realm of LINQ expression trees.
In my samples, you see a "New Int16() {}" array. That value must be parameterized at run-time with an array of values from another code element.
my query is:
from i in tblInstitutions
let ChildHasCategory = i.tblInstCtgyHistories.Where(Function(CtgyHist) CtgyHist.EndDate is Nothing AND ( (New Int16() {32,35,38,34}).Contains(CtgyHist.InstCtgyCodeFK)))
where ChildHasCategory.Any()
select i
Which can also be represented as:
tblInstitutions
.Select (i => new {
i = i,
ChildHasCategory = (IEnumerable<tblInstCtgyHistory>)(i.tblInstCtgyHistories)
.Where (
CtgyHist =>
((CtgyHist.EndDate == null) &
(IEnumerable<Int16>)(new Int16[] { 32, 35, 38, 34 } ).Contains (CtgyHist.InstCtgyCodeFK)
)
)
}
)
.Where ($VB$It => $VB$It.ChildHasCategory.Any ())
.Select ($VB$It => $VB$It.i)
This is going to be used in the context of a custom filter in an ASP.NET Dynamic Data web application. I'd like to mimic the default approach.
A sample of one of the other dynamic filter code-behind is:
Public Overrides Function GetQueryable(source As IQueryable) As IQueryable
Dim value = TextBox1.Text
If String.IsNullOrWhiteSpace(value) Then
Return source
End If
If DefaultValues IsNot Nothing Then
DefaultValues(Column.Name) = value
End If
Dim parameter = Expression.Parameter(source.ElementType)
Dim columnProperty = Expression.PropertyOrField(parameter, Column.Name)
Dim likeValue = Expression.Constant(value, GetType(String))
Dim condition = Expression.Call(columnProperty, GetType(String).GetMethod("Contains"), likeValue)
Dim where = Expression.Call(GetType(Queryable), "Where", New Type() {source.ElementType}, source.Expression, Expression.Lambda(condition, parameter))
Return source.Provider.CreateQuery(where)
End Function
I'm not sure you really need to worry about expression trees here. First off, we should be able to express your query as follows:
Dim targetCodes = new Int16() {32, 35, 38, 34 } ' This could be data driven as well
return from i in tblInstitutions
where i.tblInstCtgyHistories.Any(Function(ctgyHist) ctgyHist.EndDate is Nothing AndAlso
targetCodes.Contains(ctgyHist.InstCtgyCodeFK))
select i
Given that, under what case do you need the custom expression tree?

lua call function from a string with function name

Is it possible in lua to execute a function from a string representing its name?
i.e: I have the string x = "foo", is it possible to do x() ?
If yes what is the syntax ?
To call a function in the global namespace (as mentioned by #THC4k) is easily done, and does not require loadstring().
x='foo'
_G[x]() -- calls foo from the global namespace
You would need to use loadstring() (or walk each table) if the function in another table, such as if x='math.sqrt'.
If loadstring() is used you would want to not only append parenthesis with ellipse (...) to allow for parameters, but also add return to the front.
x='math.sqrt'
print(assert(loadstring('return '..x..'(...)'))(25)) --> 5
or walk the tables:
function findfunction(x)
assert(type(x) == "string")
local f=_G
for v in x:gmatch("[^%.]+") do
if type(f) ~= "table" then
return nil, "looking for '"..v.."' expected table, not "..type(f)
end
f=f[v]
end
if type(f) == "function" then
return f
else
return nil, "expected function, not "..type(f)
end
end
x='math.sqrt'
print(assert(findfunction(x))(121)) -->11
I frequently put a bunch of functions in a table:
functions = {
f1 = function(arg) print("function one: "..arg) end,
f2 = function(arg) print("function two: "..arg..arg) end,
...,
fn = function(arg) print("function N: argh") end,
}
Then you can use a string as an table index and run your function like this
print(functions["f1"]("blabla"))
print(functions["f2"]("blabla"))
This is the result:
function one: blabla
function two: blablablabla
I find this to be cleaner than using loadstring(). If you don't want to create a special function table you can use _G['foo'].
loadstring is not the answer here. For starters you would need a return in the string, and other details I won't go into.
THC4k has the right idea; if you have the function name in the variable x, then the call you want is
_G[x](arg1, arg2, ...)
Names are not unique, there can be many functions names foo in different namespaces. But _G['foo'] is foo in the global namespace.
It sounds like you want to do an 'eval', which is supported in Lua like so:
assert(loadstring(x))()
You'll probably want to concatenate the "()" onto x first, though.