LINQ query through Azure blobs of IEnumerable(Of IListBlobItem) - linq

I am trying to find specific Uri.AbsolutePath for the Block blob by its name. Azure Storage container contains only Block blobs. List of blobs returned from storage is IEnumerable(Of IListBlobItem).
I use FirstOrDefault to find specific blob by its name. Compiler says there is no Name property for CloudBlockBlob. This is probably related to single blob item type. Even if I use CloudBlockBlob within FirstOrDefault it is still IListBlobItem, thus Name property is missing. How to tackle this in an efficient way?
Dim storageAccount As CloudStorageAccount = CloudStorageAccount.Parse("Storage connection string")
Dim blobClient As CloudBlobClient = storageAccount.CreateCloudBlobClient()
Dim BlobList As IEnumerable(Of IListBlobItem) = blobClient.GetContainerReference("ContainerName").ListBlobs
Path= If(BlobList.FirstOrDefault(Function(CloudBlockBlob) CloudBlockBlob.Name = "ABC.pdf")?.Uri.AbsolutePath, "")

Sure, FirstOrDefault will result in an IListBlobItem according to intellisense but it has of course an actual implementation. Any debugger will tell you what actual type is returned.
In your case you are only interested in the results of ListBlobs that are actual of type CloudBlockBlob. To do that you can use the OfType method:
Dim storageAccount As CloudStorageAccount = CloudStorageAccount.Parse("Storage connection string")
Dim blobClient As CloudBlobClient = storageAccount.CreateCloudBlobClient()
Dim BlobList As IEnumerable(Of CloudBlockBlob) = blobClient.GetContainerReference("ContainerName").ListBlobs.OfType(Of CloudBlockBlob)
Path = If(BlobList.FirstOrDefault(Function(CloudBlockBlob) CloudBlockBlob.Name = "ABC.pdf")?.Uri.AbsolutePath, "")
You can probably improve you search by filtering items out on the server side using the prefix option of ListBlobs
Dim BlobList As IEnumerable(Of CloudBlockBlob) = blobClient.GetContainerReference("ContainerName").ListBlobs(prefix := "ABC.pdf").OfType(Of CloudBlockBlob)
This line will only list blobs of which the name starts with / equals to "ABC.pdf".
Disclaimer: I am not a VB.Net developer so there might me some small mistakes and some room for readability improvements.

Related

deleting a record in linq to sql (vb.net) what is wrong with my code?

I am getting the correct Employee Id in the VarEmpID variable. When I click on delete
It is giving me
Unable to cast object of type 'System.Data.Linq.DataQuery`1[my name space]' to type 'namespace'.
enter code here
Protected Sub radGrid1_DeleteCommand(ByVal source As Object, ByVal e As GridCommandEventArgs) Handles radGrid1.DeleteCommand
Dim VarEmpId As String = (CType(e.Item, GridDataItem)).OwnerTableView.DataKeyValues(e.Item.ItemIndex)("EmpId").ToString()
Using dc1 As New EmployeesDataClassesDataContext()
Dim EmployeeEntry = (From p In dc1.Employees
Where (p.EmpId = VarEmpId)
Select p)
dc1.Employees.DeleteOnSubmit(EmployeeEntry)
dc1.SubmitChanges()
Dim queryResults = (From queryItem In EmployeeEntry Select queryItem).ToList()
If queryResults.Any Then
radGrid1.DataSource = queryResults
radGrid1.DataBind()
End If
End Using
End Sub
dc1.Employees.DeleteOnSubmit(EmployeeEntry)
That method expects an Employee instance. Instead, you passed in an employee query.
Dim EmployeeEntry = ( query )
This is a query, not an entry. Consider calling Enumerable.First to get the first result of the query, and then deleting that.
Modified added Dim EmployeeEntry = (From p In dc1.Employees Where (p.EmpId = VarEmpId) Select p).singleorDefault() After that commented out the queryresults part and binded data again it solved my problem. – SmilingLily

Linq does not group in VB.Net

For educational purposes I tried to convert the following Linq expression from the book "Linq in action" into VB.net
Original C#
var list =
from book in SampleData.Books
group book by new { book.Publisher.Name, book.Subject }
into grouping
select new {
Publisher = grouping.Key.Publisher,
Subject = grouping.Key.Subject,
Book = grouping
};
My attempt:
Dim list = _books.GroupBy(Function(book) New With {.Publisher = book.Publisher.Name,
book.Subject}).
Select(Function(grouping) New With {.Publisher = grouping.Key.Publisher,
.Subject = grouping.Key.Subject,
.Books = grouping})
For Each item In list
Console.WriteLine("Publisher:" & item.Publisher & ", Subject:" & item.Subject)
For Each Book In item.Books
Console.WriteLine(" " & Book.Title)
Next
Next
This leads to the following output:
Publisher:FunBooks, Subject:Fun
Funny Stories
Publisher:Joe Publishing, Subject:Work
LINQ rules
Publisher:Joe Publishing, Subject:Work
C# on rails
Publisher:Joe Publishing, Subject:Fun
All your base are belong to us
Publisher:FunBooks, Subject:Fun
Bonjour mon Amour
I expected, that the books "LINQ rules" and "C# on rails" are grouped as well as the books "Funny Stories" and "Bonjour mon Amour" because they have the same Publisher and Subject.
My anonymous key consists a new object of two simple strings.
I already tried to search in SO, but other (or) answers do not solve my problem. Even some code translators like telerik or carlosag are no help in this case.
This is the problem:
GroupBy(Function(book) New With {.Publisher = book.Publisher.Name,
book.Subject})
That's not equivalent to the C# version, because unfortunately VB uses mutable properties in anonymous types by default, and mutable properties aren't considered as part of the hash code or equality operations. You need to make both properties "Key" properties:
GroupBy(Function(book) New With {Key .Publisher = book.Publisher.Name,
Key book.Subject})
Then it should work fine. You can read more about anonymous types in VB on MSDN.
While I applaud your efforts to translate the samples, we actually have all of the samples for LINQ in Action in C# and VB available for download from the Manning Site: http://www.manning.com/marguerie/. Also, we have added samples to the LinqPad samples to make it easy to try the samples and save your changes. See http://www.thinqlinq.com/Default/LINQ-In-Action-Samples-available-in-LINQPad.aspx for instructions on how to access that.
It appears that you are working on example 5.06b. Updating it slightly, our VB translation is:
Dim query = _
From book In SampleData.Books _
Group book.Title By book.Publisher, book.Subject Into grouping = Group _
Select _
Publisher = Publisher.Name, _
Subject = Subject.Name, _
Titles = grouping
If you want to use the Lambda syntax, you do need to specify the Key as #johnskeet indicated:
Dim list = SampleData.Books.GroupBy(Function(book) New With {
Key .Publisher = book.Publisher.Name,
Key .Subject = book.Subject}).
Select(Function(grouping) New With {
.Publisher = grouping.Key.Publisher,
.Subject = grouping.Key.Subject,
.Books = grouping})

Accessing anonymous types returned via a dynamic link query

I have been trying to access the data returned from a dynamic linq query as an anonymous type. The advice I have found suggests that I should create a custom type and use it in the Select clause with the new keyword. I was directed to the followed Question for a code example:
System.LINQ.Dynamic: Select(" new (...)") into a List<T> (or any other enumerable collection of <T>)
This was indeed an excellent example which I incorporated into my code (which is VB so I had to do some translation).
My code compiles fine but When I run it , I get the error following error:
"Value cannot be null. Parameter name: member" at the following line from the example:
bindings[i] = Expression.Bind(type.GetProperty(properties[i].Name), expressions[i]);
This seems to be linked to expressions(i), which correctly contains two items as I am returning two fields from the database table. properties(i) holds the name of those two fields correctly. Any ideas as to what the value for member is supposed to be and where it should be found? Is it something from the database?
The where clause of this query works and when I run it as an anonymous type it brings back records (or rather two fields from records). The returned fields contain data not nulls.
Here is my VB version of the code from the example provided in the earlier Question. I have bolded or ** the line where the error occurs. Any ideas as to what is causing this?
Much appreciated.
Function ParseNew() As Expression
NextToken()
ValidateToken(TokenId.OpenParen, Res.OpenParenExpected)
NextToken()
Dim properties As New List(Of DynamicProperty)()
Dim expressions As New List(Of Expression)()
Do
Dim exprPos = tokenVal.pos
Dim expr = ParseExpression()
Dim propName As String
If TokenIdentifierIs("as") Then
NextToken()
propName = GetIdentifier()
NextToken()
Else
Dim [me] As MemberExpression = TryCast(expr, MemberExpression)
If [me] Is Nothing Then Throw ParseError(exprPos, Res.MissingAsClause)
propName = [me].Member.Name
End If
expressions.Add(expr)
properties.Add(New DynamicProperty(propName, expr.Type))
If tokenVal.id <> TokenId.Comma Then Exit Do
NextToken()
Loop
ValidateToken(TokenId.CloseParen, Res.CloseParenOrCommaExpected)
NextToken()
'CODE added to support strongly-typed returns
Dim type As Type = If(newResultType, DynamicExpression.CreateClass(properties))
Dim bindings(properties.Count - 1) As MemberBinding
For i As Integer = 0 To bindings.Length - 1
**bindings(i) = Expression.Bind(type.GetProperty(properties(i).Name), expressions(i))**
Next
Return Expression.MemberInit(Expression.[New](type), bindings)
End Function

rss feed by linq

I am trying to extract the rss feed using linq. Thought it would be simple, but its is not returning any nodes. probably i have to go the channel/item node, but don't know how.
Dim rssUrl As String = "http://webclip.in/rss.aspx?u=mostliked"
Dim rssDoc As XDocument = XDocument.Load(rssUrl)
Dim rssResultSet = From node In rssDoc.Descendants("item") _
Select New With { _
.title = node.Element("title").Value, _
.link = node.Element("link").Value, _
.description = node.Element("description").Value, _
.pubDate = Date.Parse(node.Element("pubdate").Value) _
}
DataGridView1.DataSource = rssResultSet
Two issues here... First, you should correct this line:
.pubDate = Date.Parse(node.Element("pubDate").Value)
The pubDate is a case-sensitive node in XML. Secondly, your dataSource will never work because LINQ is lazy computation. You have to use ToList() or a similar method that enumerate your collection. If you debug within Visual Studio 2010, you'll see that rssResultSet does not have a value because it is only enumerated when your code calls for it. Replace with this:
DataGridView1.DataSource = rssResultSet.ToList()
My last piece of advice is to set your DataGrid to AutoGenerate it's columns.
the casing on pubdate is wrong. It should be "pubDate". otherwise, works fine.

Adding a new user to CRM 4.0 using sdk

Does anyone have sample code to add a new user to CRM 4.0 using sdk?
I have code that creates users for us based on users in another system so I can't exactly paste it all here - most of it wouldn't make sense to you - but this is the core of it:
[In VB sorry :-) - also when posting VB here I find I need to use '//' to indicate a comment to make the formatting correct]
Public Sub CreateNewUser()
Dim s as mscrm.CrmService = GetMyService()
Dim newUser as New mscrm.systemuser()
With newUser
.domainname = "domain\user"
.firstname = "Stan"
.lastname = "Molda"
//set anything else you want here
End With
Dim userGuid as guid = s.Create(newUser)
//Next we need to assign the user a role
AssignRole(userGuid)
//Finally we need to assign them to the correct Time Zone
SetUserTimeZone(userGuid)
End Sub
Public Sub AssignRole(g as Guid)
Dim s as mscrm.CrmService = GetMyService()
Dim req As New mscrm.AssignUserRolesRoleRequest()
req.UserId = g
req.RoleIds = New Guid() {GetTheGuidForMyPrimaryRole()}
s.Execute(req)
End Sub
Public Sub SetUserTimeZone(g as Guid)
Dim s as mscrm.CrmService = GetMyService()
Dim r As New mscrm4.RetrieveUserSettingsSystemUserRequest()
r.ColumnSet = New mscrm3.AllColumns()
r.EntityId = New Guid(g)
Dim resp As mscrm.RetrieveUserSettingsSystemUserResponse = CType(s.Execute(r), mscrm.RetrieveUserSettingsSystemUserResponse)
Dim settings As mscrm.usersettings = CType(resp.BusinessEntity, mscrm.usersettings)
settings.timezonecode = New mscrm.CrmNumber
settings.timezonecode.Value = OUR_TIME_ZONE_CONSTANT
Dim update As New mscrm.UpdateUserSettingsSystemUserRequest()
update.Settings = settings
update.UserId = g
s.Execute(update)
End Sub
For C#, take a look at my question, Dynamics CRM: Create users with specific GUIDs, which does exactly what you want (but not exactly what I want :-P).

Resources