When i am performing large imports from data to put into sql using entity framework, my code has to check the same foreign keys that results in repetitive commands to the sql server. I believe i need to use 2nd level cache, i have tried to use the efcache from nuget, but as i am only used to vb.net, i am having trouble converting the following c# code:
public class Configuration : DbConfiguration
{
public Configuration()
{
var transactionHandler = new CacheTransactionHandler(new InMemoryCache());
AddInterceptor(transactionHandler);
Loaded +=
(sender, args) => args.ReplaceService<DbProviderServices>(
(s, _) => new CachingProviderServices(s, transactionHandler,
new DefaultCachingPolicy()));
}
}
to vb
Imports System.Data.Entity
Imports EFCache
Public Class Configuration
Inherits DbConfiguration
Public Sub New()
Dim transactionHandler = New CacheTransactionHandler(New InMemoryCache())
AddInterceptor(transactionHandler)
AddHandler Loaded, Function(sender, args) args.ReplaceService(Of
DbProviderServices)(Function(s, _) New CachingProviderServices(s,
transactionHandler, New DefaultCachingPolicy()))
End Sub
End Class
I understand that i need to change c# += to addhandler, but it doesnt recognise dbproviderservices, the underscore _ and DefaultCachingPolicy.
You are using incorrect method signatures.
DbConfiguration.Loaded
Public Shared Event Loaded As EventHandler(Of DbConfigurationLoadedEventArgs)
DbConfigurationLoadedEventArgs.ReplaceService(Of TService)
Public Sub ReplaceService(Of TService) (serviceInterceptor As Func(Of TService, Object, TService))
So the code should look more like this:
AddHandler Loaded,
Sub(sender As Object, e As DbConfigurationLoadedEventArgs)
e.ReplaceService(Of DbProviderServices)(
Function(serviceInterceptor As DbProviderServices, o As Object)
Return New CachingProviderServices(serviceInterceptor, transactionHandler, New DefaultCachingPolicy())
End Function)
End Sub
Compact version:
AddHandler Loaded, Sub(sender As Object, e As DbConfigurationLoadedEventArgs) e.ReplaceService(Of DbProviderServices)(Function(serviceInterceptor As DbProviderServices, o As Object) New CachingProviderServices(serviceInterceptor, transactionHandler, New DefaultCachingPolicy()))
Related
to create functionallity in my project I need to convert this C# sample to vb.net
I can only connect (Read/Write) to the backend using this API.
to get the details of a customer from a database:
Customer.BeginFetch(CustomerId, AfterFetchingCustomer);
private void AfterFetchingCustomer(object sender, DataPortalResult<Customer> dataPortalResult)
{
Invoke((Action)(() =>
{
_customer = dataPortalResult.Object;
txtShortName.Text = _customer.ShortName;
}));
}
//This is from the API in C#
public static void BeginFetch(string customerId, EventHandler<DataPortalResult<Customer>> callback, AdministrationContext context = null);
I tried:
Dim Debb Debiteur.CustomerId = "DE16000"
Customer.BeginFetch(Debiteur, AfterFetchingCustomer)
End Sub
Private Sub AfterFetchingCustomer(sender As Object, e As DataPortalResult(Of Customer))
End Sub
''This is from the API in VB:
Public Shared Sub BeginFetch(customerId As String, callback As EventHandler(Of DataPortalResult(Of Customer)), Optional context As AdministrationContext = Nothing)
But still get the errors:
Argument not specified for parameter sender ...
Argument not specified for parameter e ...
How can i get this code validated?
So I can continue to work on this program.
Thanks in advance!
ina c# project i have a static async task written to send emails via tmpt-relay.
the main function is calling this task.
This is working fine.
My Problem is i'm calling this function from a vb.net project, this is also working, email was send but vb.net is hanging in the c#-call
My Code in c#
public class SmoffMail
{
public static string sRet;
public string sendMail(string mailto)
{
RunAsync(mailto).Wait();
return sRet;
}
static async Task RunAsync(string mailto){
MailjetClient client = new MailjetClient("419cce0b9807d1016642156966fc4ec1",
....
sRet = "ok.....";
}
}
From the vb.net i call it like this:
Public Class Form1
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim smail As New smoff.Mailjet.SmoffMail
Dim i As Integer = 0
Dim sRet As String = ""
sRet = smail.sendMail("xxxxxxxh#bluewin.ch")
MsgBox(sRet)
End Sub
End Class
So the function smail.sendMail() was called but is hanging, the next line in code ( msgbox ) is nerver attempt.
Thanks for your help
Your C# should look like this:
public class SmoffMail
{
static async Task<string> SendMailAsync(string mailto){
MailjetClient client = new MailjetClient("419cce0b9807d1016642156966fc4ec1",
....
return "ok.....";
}
}
And your VB should look like this:
Public Class Form1
Private Async Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim sRet As String = ""
sRet = Await smoff.Mailjet.SmoffMail.SendMailAsync("xxxxxxxh#bluewin.ch")
MsgBox(sRet)
End Sub
End Class
Let your VB go back to drawing the UI while it waits for your 2 gigabyte attachment to upload, otherwise there's no point in having any of this be async
i found the solution, the problem was not my code, it was the API Mailjet.client.
after changing the call to this API it works fine
This question already has answers here:
VB.NET equivalent to C# var keyword [duplicate]
(4 answers)
Closed 8 years ago.
I'm looking at trying to implement a mediator helper class to facilitate the transfer of information between viewmodels.
Starting with the following in c#
static public class Mediator
{
static IDictionary<string, List<Action<object>>> pl_dict = new Dictionary<string, List<Action<object>>>();
static public void Register(string token, Action<object> callback)
{
if (!pl_dict.ContainsKey(token))
{
var list = new List<Action<object>>();
list.Add(callback);
pl_dict.Add(token, list);
}
else
{
bool found = false;
foreach (var item in pl_dict[token])
if (item.Method.ToString() == callback.Method.ToString())
found = true;
if (!found)
pl_dict[token].Add(callback);
}
}
static public void Unregister(string token, Action<object> callback)
{
if (pl_dict.ContainsKey(token))
pl_dict[token].Remove(callback);
}
static public void NotifyColleagues(string token, object args)
{
if (pl_dict.ContainsKey(token))
foreach (var callback in pl_dict[token])
callback(args);
}
}
I end up with the following in vb (courtesy of telerik's online converter
Public NotInheritable Class Mediator
Private Sub New()
End Sub
Shared pl_dict As IDictionary(Of String, List(Of Action(Of Object))) = New Dictionary(Of String, List(Of Action(Of Object)))()
Public Shared Sub Register(token As String, callback As Action(Of Object))
If Not pl_dict.ContainsKey(token) Then
Dim list = New List(Of Action(Of Object))()
list.Add(callback)
pl_dict.Add(token, list)
Else
Dim found As Boolean = False
For Each item As var In pl_dict(token)
If item.Method.ToString() = callback.Method.ToString() Then
found = True
End If
Next
If Not found Then
pl_dict(token).Add(callback)
End If
End If
End Sub
Public Shared Sub Unregister(token As String, callback As Action(Of Object))
If pl_dict.ContainsKey(token) Then
pl_dict(token).Remove(callback)
End If
End Sub
Public Shared Sub NotifyColleagues(token As String, args As Object)
If pl_dict.ContainsKey(token) Then
For Each callback As var In pl_dict(token)
callback(args)
Next
End If
End Sub
End Class
The compiler doesn't like the two For Each <...> As var statements. I'm assuming that this is linq c# style which has always been very difficult to translate with ease. This one has me ostensibly because I'm still trying to fathom out the whole principle anyway. Can anyone suggest a proper construct for the two lines in question.
Thanks
In VB, the equivalent of var is to simply declare the variable without specifying the type, for instance:
For Each callback In pl_dict(token)
callback(args)
Next
However, in order for that to work, you need to have Option Infer On. Alternatively, you could just specify the type of the iterator variable as whatever it actually is (in this case, Action(Of Object)), like this:
For Each callback As Action(Of Object) In pl_dict(token)
callback(args)
Next
Question:
I have this C# program, that gets the value of field tablename of mytable.
And it works fine.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows.Forms;
namespace AttachObjectsCS
{
static class Program
{
public class cmytable
{
public string tablename = "test";
}
// http://stackoverflow.com/questions/2616638/access-the-value-of-a-member-expression
private static object GetValue(System.Linq.Expressions.MemberExpression member)
{
System.Linq.Expressions.Expression objectMember = System.Linq.Expressions.Expression.Convert(member, typeof(object));
System.Linq.Expressions.Expression<Func<object>> getterLambda = System.Linq.Expressions.Expression.Lambda<Func<object>>(objectMember);
var getter = getterLambda.Compile();
return getter();
}
public static void AddField<T>(System.Linq.Expressions.Expression<Func<T>> expr, string alias)
{
var body = ((System.Linq.Expressions.MemberExpression)expr.Body);
Console.WriteLine("Name is: {0}", body.Member.Name);
object obj = GetValue(body);
Console.WriteLine("Value is: {0}", obj);
}
/// <summary>
/// Der Haupteinstiegspunkt für die Anwendung.
/// </summary>
[STAThread]
static void Main()
{
if (false)
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form1());
}
cmytable mytable = new cmytable();
AddField(() => mytable.tablename, "te");
Console.WriteLine(Environment.NewLine);
Console.WriteLine(" --- Press any key to continue --- ");
Console.ReadKey();
} // End Sub Main
} // End Class Program
} // End Namespace AttachObjectsCS
Now I need the same functionality in VB.NET, but it fails.
Now since I'm aware that VB.NET and C# don't always use the same linq expression, I'm not surprised that I run into a problem here.
Module Program
Public Class cmytable
Public tablename As String = "test"
End Class
Public Sub AddField(Of T)(expr As System.Linq.Expressions.Expression(Of Func(Of T)))
Dim body = DirectCast(expr.Body, System.Linq.Expressions.MemberExpression)
Dim strName As String = body.Member.Name
Console.WriteLine("Name is: {0}", strName)
Dim obj As Object = GetValue(body)
Console.WriteLine("Value is: {0}", obj)
End Sub
' http://stackoverflow.com/questions/2616638/access-the-value-of-a-member-expression '
Private Function GetValue(member As System.Linq.Expressions.MemberExpression) As Object
Dim objectMember As System.Linq.Expressions.Expression = System.Linq.Expressions.Expression.Convert(member, GetType(Object))
Dim getterLambda As System.Linq.Expressions.Expression(Of Func(Of Object)) = System.Linq.Expressions.Expression.Lambda(Of Func(Of Object))(objectMember)
Dim getter = getterLambda.Compile()
Return getter()
End Function
Public Sub Main()
Dim mytable As New cmytable
AddField(Function() mytable.tablename)
End Sub
End Module ' Program
The problem is in GetValue, and the problem is that I don't seem to have the proper objectMember.
Here the debug output for the expressions:
CS objectMember = {Convert(value(AttachObjectsCS.Program+<>c__DisplayClass0).mytable.tablename)}
VB objectMember = {Convert(value(AttachObjects.Program+_Closure$__1).$VB$Local_mytable.tablename)}
CS getterLambda = {() => Convert(value(AttachObjectsCS.Program+<>c__DisplayClass0).mytable.tablename)}
VB getterLambda = {() => Convert(value(AttachObjects.Program+_Closure$__1).$VB$Local_mytable.tablename)}
My guess would be that the problem is the $VB$Local_ in $VB$Local_mytable.tablename
Now I'm wondering what I have to change for this to work in VB.NET.
Anybody knows / has a clue ?
Edit:
Ah, the problem seems to be caused by "Option Infer Off" in the project wide settings.
So the the question alters and becomes: How to do this with "Option Infer Off" ?
Your problem has nothing to do with expression trees (which would be easier to spot if you bothered to include the error you're getting).
You have Option Infer Off and Option Strict Off and the following code:
Dim getter = getterLambda.Compile()
Return getter()
which throws MissingMemberException:
No default member found for type 'Func(Of Object)'.
The problem is that () is here interpreted as invoking the default member and not invoking a delegate, because getter is typed as Object. To work around that, you can specify the type of the variable:
Dim getter As Func(Of Object) = getterLambda.Compile()
Return getter()
or you can use more verbose syntax for invoking a delegate:
Dim getter = getterLambda.Compile()
Return getter.Invoke()
[Visual C#]
public ICommand MyCommand
{
get
{
if (this.myCommand == null)
{
this.myCommand = new RelayCommand(this.ShowMyCommand);
}
return this.myCommand;
}
}
private void ShowMyCommand(object param)
{
...
}
This code works fine, but when I convert it to Visual Basic:
[Visual Basic]
Private _myCommand As RelayCommand
Public ReadOnly Property MyCommand As ICommand
Get
If Me._myCommand Is Nothing Then
Me._myCommand = New RelayCommand(Me.ShowMyCommand)
End If
Return Me._myCommand
End Get
End Property
Private Sub ShowMyCommand(ByVal param As Object)
...
End Sub
I get the error:
Error 3 Argument not specified for
parameter 'param' of 'Private Sub
ShowMyCommand(param As Object)'.
Any ideas? I am just doing blind conversion so I don't understand what the project does, I am just converting it.
I am a bit on thin ice when it comes to VB, but according to what I know, you need to prefix the method name with the keyword AddressOf in order for it to be usable as a method group for the event.
The following line:
Me._myCommand = New RelayCommand(Me.ShowMyCommand)
Needs to be written as:
Me._myCommand = New RelayCommand(AddressOf Me.ShowMyCommand)
The error message is because the compiler is trying to compile a call to the method, and is thus missing the argument to its parameter.