How to dynamically pass connectionstrings in EF5 - wpf

I'm struggling with a project, converted to .net 4.5.
I have some functions like this:
Public Shared Function Load(iJaar As Integer, iKwartaal As Integer) As List(Of LoonDetail_121)
Dim oLoonDetails As New List(Of LoonDetail_121)
Try
Dim oDB As New SDWMasterSDWDBEntities(DBConnections.ConnStringPrisma)
Dim dStartDate As New Date(iJaar, ((iKwartaal - 1) * 3) + 1, 1)
Dim dEndDate As New Date(iJaar, ((iKwartaal - 1) * 3) + 4, 1)
oLoonDetails = oDB.LoonDetail_121.Where(Function(x) x.EindPeriode_121 >= dStartDate And
x.EindPeriode_121 < dEndDate).ToList
Catch ex As Exception
Throw New Exception(GetCurrentMethod.Name & " " & ex.Message)
End Try
Return oLoonDetails
End Function
When I convert this function to EF5, I get errors, since my SDCDBLonenEntities is not inherited anymore from ObjectContext, but it is inherited from DbContext.
Before, EF automatically created a constructor where I can pass my Connection String.
This is very easy, because I use different connectionstrings, depending on my Solution Configuration (Debug/Release).
In EF5, the constructor doesn't accept Connectionstrings anymore.
I tried to create a partial class of my Entity, and create my own constructor, but I can't get this working:
Partial Public Class SDWMasterSDWDBEntities
Inherits DbContext
Public Sub New(sConnString As String)
MyBase.New(sConnString)
End Sub
End Class
For another project, I adapted my Project-file to use different app.config files for each solution configuration, but that was a p.i.t.a to maintain and for me not a clean solution.
So my question is: How can I use EF5 with my own personal Connectionstrings?
These are my Connection Strings by the way:
#If DEBUG Then
Friend ConnStringSDW As String = "metadata=res://*/Entities.SDWDB.csdl|res://*/Entities.SDWDB.ssdl|res://*/Entities.SDWDB.msl;provider=System.Data.SqlClient;provider connection string='data source=SDWDB01\SDWSQL;initial catalog=SDWDB_DEV;persist security info=True;user id=usr;password=pwd;multipleactiveresultsets=True;App=EntityFramework'"
#Else
Friend ConnStringSDW As String = "metadata=res://*/Entities.SDWDB.csdl|res://*/Entities.SDWDB.ssdl|res://*/Entities.SDWDB.msl;provider=System.Data.SqlClient;provider connection string='data source=SDWDB01\SDWSQL;initial catalog=SDWDB_PROD;persist security info=True;user id=usr;password=pwd;multipleactiveresultsets=True;App=EntityFramework'"
#End If
And I get the error "The entity type SDW_USERS_MASTER is not part of the model for the current context.", when I execute this function:
Public Shared Function LoadAll() As List(Of SDW_USERS_MASTER)
Dim oUsers As New List(Of SDW_USERS_MASTER)
Try
Using oDB As New SDWMaster.SDWMasterSDWDBEntities(DBConnections.ConnStringSDW)
oUsers = (From tmpUsers In oDB.SDW_USERS_MASTER
Select tmpUsers).ToList.OrderBy(Function(x) x.Login).ToList
End Using
Catch ex As Exception
Debug.Print(ex.Message)
Throw New Exception(GetCurrentMethod.Name & " " & ex.Message)
End Try
Return oUsers
End Function

Create a new partial class with the same name as your context, then overload the constructor. So, if your context class is named "myContext", then you would have:
Imports System
Imports System.Data.Entity
Imports System.Data.Entity.Infrastructure
Imports System.Data.Objects
Imports System.Data.Objects.DataClasses
Imports System.Linq
Partial Public Class myContext
Inherits DbContext
Public Sub New(connectionString As String)
MyBase.New(connectionString)
End Sub
End Class

Related

How To MustOverride Shared/Constructor Function Visual Basic

I'm currently using Visual Basic for a College Project which requires us to make a simple database system. For my system I have a base(abstract) class called Record which is inherited by the different types of records there are in my database e.g. Member, User, Role.
I am saving my data in csv files and have already written a CSVHandler class. However, I want an elegant way of constructing an instance of a class derived from Record with a string from the CSVHandler.
This is where the problem occurs. The only way I can think of doing this is by making a Constrcutor or Shared Function in each class derived from Record. However, Visual Basic does not allow you make Constructors or Shared Functions also MustOverride.
Here is the code I would expect to write:
' Base Class
Public MustInherit Class Record
Public MustOverride Shared Function fromString(ByVal str as String) As Record
End Class
' Example Of Class Derived From Record
Public Class User
Inherits Record
Private _id As String
Private _name As String
Public Sub New(ByVal id As String, ByVal name As String)
_id = id
_name = name
End Sub
Public Overrides Shared Function fromString(ByVal str as String) As Record
Dim strs() As String = str.Split(",")
Return New User(strs(0), strs(1))
End Function
End Class
' Example Of Creating Instacnce Of User
Dim user1 = User.fromString("1671,Kappeh")
Is there a way to achieve this effect?
Have your constructor call a Protected MustOverride method that does the initialisation.
Public MustInherit Class Record
'This is required because each derived constructor must be able to implicitly invoke a parameterless
'base constructor if it doesn't explicitly invoke a base constructor with parameters.
Protected Sub New()
End Sub
Public Sub New(csv As String)
Init(csv)
End Sub
Protected MustOverride Sub Init(csv As String)
End Class
Public Class User
Inherits Record
Private Property Id As String
Private Property Name As String
'This is still required because you can use a base constructor directly to create a derived instance.
Public Sub New(csv As String)
MyBase.New(csv)
End Sub
Public Sub New(id As String, name As String)
Id = id
Name = name
End Sub
Protected Overrides Sub Init(csv As String)
'Add your type-specific implementation here.
End Sub
End Class
This "solution" doesn't actually do what I thought it would because, while it forces you to override Init in a derived class, you still have to provide a derived constructor that invokes the base constructor that calls Init and you still can't enforce that. I think that I'll leave this as an answer though, because, while it doesn't actually provide a solution to your problem, it demonstrates further why (as far as I can tell) there is no such solution.
The following is similar to the answer from #jmcilhinney in that it forces the derived class to implement an initialization method. However it makes use of a generic shared function and uses the little known GetUninitializedObject method to get around using the generic New constraint and it's requirement of an accessible parameter-less constructor.
Public MustInherit Class Record
Public Shared Function fromString(Of T As {Record})(ByVal str As String) As T
' create an unintialized instance of T
Dim ret As T = DirectCast(System.Runtime.Serialization.FormatterServices.GetUninitializedObject(GetType(T)), T)
ret.Initialize(str)
Return ret
End Function
Protected MustOverride Sub Initialize(source As String)
End Class
The User class then would be something like this:
Public Class User : Inherits Record
Private _id As String
Private _name As String
Public Sub New(ByVal id As String, ByVal name As String)
_id = id
_name = name
End Sub
Protected Overrides Sub Initialize(source As String)
Dim strs() As String = source.Split(","c)
_id = strs(0)
_name = strs(1)
End Sub
End Class
Example usage:
Dim userRecord As User = Record.fromString(Of User)("1,2")

SSIS Script Task not working in Visual Studio 2010, Exception has been thrown by the target of an invocation

I am using SSIS Script Task but whenever I am running it the the SSIS package fails and it gives the following error: Exception has been thrown by the target of an invocation.
Is it possible that it is giving this issue because I was using this script in Visual Studio 2008 and I am trying to implement the package in Visual Studio 2010.
here is my code:
enter code here ' Microsoft SQL Server Integration Services Script Task
' Write scripts using Microsoft Visual Basic 2008.
' The ScriptMain is the entry point class of the script.
Imports System
Imports System.Data
Imports System.Math
Imports Microsoft.SqlServer.Dts.Runtime
Imports System.IO
<Microsoft.SqlServer.Dts.Tasks.ScriptTask.SSISScriptTaskEntryPointAttribute> _
<System.CLSCompliantAttribute(False)> _
Partial Public Class ScriptMain
Inherits
Microsoft.SqlServer.Dts.Tasks.ScriptTask.VSTARTScriptObjectModelBase
Enum ScriptResults
Success = Microsoft.SqlServer.Dts.Runtime.DTSExecResult.Success
Failure = Microsoft.SqlServer.Dts.Runtime.DTSExecResult.Failure
End Enum
' The execution engine calls this method when the task executes.
' To access the object model, use the Dts property. Connections, variables, events,
' and logging features are available as members of the Dts property as shown in the following examples.
'
' To reference a variable, call Dts.Variables("MyCaseSensitiveVariableName").Value
' To post a log entry, call Dts.Log("This is my log text", 999, Nothing)
' To fire an event, call Dts.Events.FireInformation(99, "test", "hit the help message", "", 0, True)
'
' To use the connections collection use something like the following:
' ConnectionManager cm = Dts.Connections.Add("OLEDB")
' cm.ConnectionString = "Data Source=localhost;Initial Catalog=AdventureWorks;Provider=SQLNCLI10;Integrated Security=SSPI;Auto Translate=False;"
'
' Before returning from this method, set the value of Dts.TaskResult to indicate success or failure.
'
' To open Help, press F1.
Public Sub Main()
Dim file_stream As New FileStream(CType(ReadVariable("filepath"), String) + "AIR_FEE1.TRN", FileMode.Append)
Using w As New StreamWriter(file_stream, Text.Encoding.UTF8)
w.WriteLine("T|" + CType(ReadVariable("Count"), String))
End Using
Dim FName As String
Dim LFName As String
FName = CType(ReadVariable("filename"), String)
LFName = CType(ReadVariable("logfile"), String)
WriteVariable("StaticLogFileName", LFName)
WriteVariable("StaticFileName", FName)
Dim file_stream1 As New FileStream("StaticFileName", FileMode.Create)
file_stream.Close()
Dts.TaskResult = ScriptResults.Success
End Sub
Private Function ReadVariable(ByVal varName As String) As Object
Dim result As Object
Try
Dim vars As Variables
Dts.VariableDispenser.LockForRead(varName)
Dts.VariableDispenser.GetVariables(vars)
Try
result = vars(varName).Value
Catch ex As Exception
Throw ex
Finally
vars.Unlock()
End Try
Catch ex As Exception
Throw ex
End Try
Return result
End Function
Private Sub WriteVariable(ByVal varName As String, ByVal varValue As Object)
Try
Dim vars As Variables
Dts.VariableDispenser.LockForWrite(varName)
Dts.VariableDispenser.GetVariables(vars)
Try
vars(varName).Value = varValue
Catch ex As Exception
Throw ex
Finally
vars.Unlock()
End Try
Catch ex As Exception
Throw ex
End Try
End Sub
End Class
First of all, "Exception has been thrown by the target of an invocation" is a generic message that is thrown when an error occurred during script task execution, try to debug your code to find a more precise error message.
I think you can write the same script without defining functions to manipulate your variables:
Public Sub Main()
Dim file_stream As New FileStream(Dts.Variables("filepath").Value + "AIR_FEE1.TRN", FileMode.Append)
Using w As New StreamWriter(file_stream, Text.Encoding.UTF8)
w.WriteLine("T|" + Dts.Variables("Count").Value)
End Using
Dim FName As String
Dim LFName As String
FName = Dts.Variables("filename").Value
LFName = Dts.Variables("logfile").Value
Dts.Variables("StaticLogFileName").Value = LFName
Dts.Variables("StaticFileName").Value = FName
Dim file_stream1 As New FileStream("StaticFileName", FileMode.Create)
file_stream.Close()
Dts.TaskResult = ScriptResults.Success
End Sub
Make sure that you have selected your ReadOnly Variables and ReadWrite Variables properly from the Script task properties form.
Helpful links
Using Variables in the Script Task
3 Ways -SSIS Read Write Variables – Script Task C# / VB.net
Unable to fetch "ReadWrite" Variable Value in Script Component of SSIS

Error Handling in SSIS

I have created a SSIS package which gets the XML file from a folder and checks with the schema, if the schema fails, the package logs the error and moves the file to a error folder. Currently, I have done all the requirements, and is working fine except the error message i'm getting at the end of the execution.
Validate XML file
The error message which I'm getting
The error message which I'm getting
The package works fine as expected. How can I suppress this error message?
Update #1:
This is my error history
This is my XML Schema validation task properties.
Suggestions
The issue may be caused by the FailPackageOnFailure and FailParentOnFailure properties. Click on the Validate XML Task and in the Properties Tab change these properties values. Alos in the Control Flow Go to the properties and change the MaximumErrorCount value and make it bigger than 1.
Also you can find other helpful informations in this link:
Continue Package Execution After Error In SSIS
Workaround using Script Task
Add 3 Variables to your package:
#[User::XmlPath] Type: String, Description: Store the Xml File Path
#[User:XsdPath] Type: String, Description: Store the Xsd File Path
#[User:IsValidated] Type: Boolean, Description: Store the result of Xml validation
Add a script Task, select XmlPath and User:XsdPath as ReadOnly Variables and IsValidated As ReadWrite Variable
Set the Script Language to Visual Basic
In the Script Editor write the following code (this is the whole script task code)
#Region "Imports"
Imports System
Imports System.Collections.Generic
Imports System.Data
Imports System.Math
Imports System.Text
Imports System.Xml
Imports System.Xml.Schema
Imports Microsoft.SqlServer.Dts.Runtime
#End Region
<Microsoft.SqlServer.Dts.Tasks.ScriptTask.SSISScriptTaskEntryPointAttribute()>
<System.CLSCompliantAttribute(False)>
Partial Public Class ScriptMain
Inherits Microsoft.SqlServer.Dts.Tasks.ScriptTask.VSTARTScriptObjectModelBase
Enum ScriptResults
Success = Microsoft.SqlServer.Dts.Runtime.DTSExecResult.Success
Failure = Microsoft.SqlServer.Dts.Runtime.DTSExecResult.Failure
End Enum
Public Function LoadXml(xmlFilePath As String, xsdFilePath As String) As Boolean
Dim settings As New XmlReaderSettings()
settings.Schemas.Add(Nothing, xsdFilePath)
settings.ValidationType = ValidationType.Schema
Dim errorBuilder As New XmlValidationErrorBuilder()
AddHandler settings.ValidationEventHandler, New ValidationEventHandler(AddressOf errorBuilder.ValidationEventHandler)
Dim reader As XmlReader = XmlReader.Create(xmlFilePath, settings)
' Read the document...
Dim errorsText As String = errorBuilder.GetErrors()
If errorsText IsNot Nothing Then
Return False
Else
Return True
End If
End Function
Public Sub Main()
Dts.Variables("IsValidated").Value = LoadXml(Dts.Variables("XmlPath").Value.ToString, Dts.Variables("XsdPath").Value.ToString)
Dts.TaskResult = ScriptResults.Success
End Sub
End Class
Public Class XmlValidationErrorBuilder
Private _errors As New List(Of ValidationEventArgs)()
Public Sub ValidationEventHandler(ByVal sender As Object, ByVal args As ValidationEventArgs)
If args.Severity = XmlSeverityType.Error Then
_errors.Add(args)
End If
End Sub
Public Function GetErrors() As String
If _errors.Count <> 0 Then
Dim builder As New StringBuilder()
builder.Append("The following ")
builder.Append(_errors.Count.ToString())
builder.AppendLine(" error(s) were found while validating the XML document against the XSD:")
For Each i As ValidationEventArgs In _errors
builder.Append("* ")
builder.AppendLine(i.Message)
Next
Return builder.ToString()
Else
Return Nothing
End If
End Function
End Class
Use Precedence Constraints with expression to manipulate both of Validation success and failure cases
Script Code Reference
VB.NET validating XML file against XSD file and parsing through the xml

Change connection EF at runtime in WPF app

I have a WPF app that I'd like to change the connection string programmatically when the app loads. I use the Database-First approach for EF.
I spent a lot of time implementing various solutions found online including stack overflow and can't seem to get it to work.
The most common way seems to be to modify the Entity partial class. When I do this I get the following error at runtime:
Additional information: The context is being used in Code First mode with code that was generated from an EDMX file for either Database First or Model First development. This will not work correctly. To fix this problem do not remove the line of code that throws this exception. If you wish to use Database First or Model First, then make sure that the Entity Framework connection string is included in the app.config or web.config of the start-up project. If you are creating your own DbConnection, then make sure that it is an EntityConnection and not some other type of DbConnection, and that you pass it to one of the base DbContext constructors that take a DbConnection. To learn more about Code First, Database First, and Model First see the Entity Framework documentation here: http://go.microsoft.com/fwlink/?LinkId=394715
I got the same error implementing various other ways as well. If someone could please help me implement a way to change the connection string at runtime I'd greatly appreciate it.
My current implementation is taken from this example solution:
Changing Databases at Run-time using Entity Framework
Implementation:
App.config containts the connection string and name
Partial class added with same name as Entity class:
Imports System.Data.Entity
Imports System.Data.EntityClient
Imports System.Data.SqlClient
Partial Public Class MyEntityName
Inherits DbContext
Public Sub New(ByVal connString As String)
MyBase.New(connString)
End Sub
End Class
In my Application.xaml code file I set a global string variable by calling a method that builds the EntityConnectionStringBuilder. This global string variable is then passed into an entity constructor.
Imports System.Reflection
Imports DevExpress.Xpf.Core
Imports System.Data.EntityClient
Class Application
Public Sub New()
entityConnStr = BuildConnectionString("[MyDataSource]", "[MyDatabase]")
End Sub
Private Function BuildConnectionString(ByVal DataSource As String, ByVal Database As String) As String
' Build the connection string from the provided datasource and database
Dim connString As String = "data source=" & DataSource & ";initial catalog=" & Database & ";persist security info=True;user id=[user];password=[password];trustservercertificate=True;MultipleActiveResultSets=True;App=EntityFramework""
' Build the MetaData... feel free to copy/paste it from the connection string in the config file.
Dim esb As New EntityConnectionStringBuilder()
esb.Metadata = "res://*/DB.[MyEntityName].csdl|res://*/DB.[MyEntityName].ssdl|res://*/DB.[MyEntityName].msl"
esb.Provider = "System.Data.SqlClient"
esb.ProviderConnectionString = connString
' Generate the full string and return it
Return esb.ToString()
End Function
Usage:
Using context = New MyEntity("entityConnStr")
Public connection variable string:
Public entityConnStr As String
I think you should remove the quotes when you pass the connection string to the constructor. You want to use the variable contents, not the variable name.
Use this:
Using context = New MyEntity(entityConnStr)
Instead of this:
Using context = New MyEntity("entityConnStr")

ListBox ObservableCollection duplicating

I have a WPF application which has a listbox bound to an ObservableCollection which retrieves it's data from a Database. I am attempting to have the ListBox data refreshed every minute through the use of a DispatcherTimer.
Dim dispatcherTimer As DispatcherTimer = New System.Windows.Threading.DispatcherTimer
AddHandler dispatcherTimer.Tick, AddressOf getRoomMeetingDetails
dispatcherTimer.Interval = New TimeSpan(0, 2, 0)
dispatcherTimer.Start()
Which calls the getRoomMeetingDetails method as follows.
Public Sub getRoomMeetingDetails()
If Not My.Settings.rbConn = Nothing And _
Not gl_rmName = Nothing Then
Dim sqlConn As New SqlConnection(My.Settings.rbConn)
Dim sqlquery As String = "SELECT *" & _
"FROM table " & _
Dim sqlCmd As New SqlCommand(sqlquery, sqlConn)
sqlConn.Open()
Dim dr As SqlDataReader
dr = sqlCmd.ExecuteReader
While dr.Read
roomMeetingList.Add(New meetingDetails() With {.eMeetingId = dr.Item("dId")})
End While
End If
End Sub
I then have my two classes for the Collection as follows (I am very new to ObservableCollections and have tried my best to model my code off the MSDN examples, so if this isn't the best method to use to achieve what I am trying to achieve, or can be done easier, please let me know)
Public Class MeetingList
Inherits ObservableCollection(Of meetingDetails)
Private Shared list As New MeetingList
Public Shared Function getList() As MeetingList
Return list
End Function
Private Sub New()
AddItems()
End Sub
Public Shared Sub reset(ByVal rmName As String)
list.ClearItems()
list.AddItems()
End Sub
Private Sub AddItems()
End Sub
End Class
Public Class meetingDetails
Implements INotifyPropertyChanged
Public Sub New()
End Sub
Public Property eID() As String
Get
Return _eID
End Get
Set(ByVal value As String)
_eID = value
OnPropertyChanged("eID")
End Set
End Property
Private _eID As String
Public Event PropertyChanged As PropertyChangedEventHandler _
Implements INotifyPropertyChanged.PropertyChanged
End Class
What is happening is when the DispatcherTimer is called every minute, the ListBox data is duplicated which I believe is because the getRoomMeetingDetails method is adding all of the SQL results on every tick. How can I refresh the ListBox with only new data or data changes from the table?
I am really struggling to work out where I am going wrong and what needs to be added/removed for this to work.
If there is any details I am missing please let me know.
Matt
Either you clear all the data in the listbox before adding them again or you do a check on the collection. I assume your eID is the primary key? the do something like this:
if ( roomMeetingList.Where ( entry => entry.eID == dbID ).Count () == 0 ) {
// add
}
C# code, but it shows the idea
developerFusion's convert made this VB:
If roomMeetingList.Where(Function(entry) entry.eID = dbID).Count() = 0 Then
' Add
End If

Resources