I am developing a set of Office add ins that reads and writes templates and other files from a locally stored serialized object. Until now it has been going well, however, since I have been stress testing it by writing big amounts of data to this local object, and loading it into memory when reading from it, I have been getting SystemOutOfMemory exceptions. I do clean memory out each time I am done with this object, but simply loading it into memory can cause the exception be thrown.
The object is at most 100mb in size at any given time, so there is no way that it is using all the desktop resources to load this object into memory, so I have been wondering whether it may be that Microsoft limits the amount of memory that an add in may use.
What I would like to know is of anyone knows if there is a size limit and what it may be, as well as how to increase it if there is a limit present?
Thank you in advance for any advice given.
UPDATE:
Here is the code of the class that I am serializing:
Imports System.Environment
Imports Microsoft.Win32.SafeHandles
Imports System.Runtime.InteropServices
<Serializable()> _
Public Class LocalDBObject
Private aOfficesDS As DataSet = New DataSet()
Private aFieldDS As DataSet = New DataSet()
Private aSectorsDS As DataSet = New DataSet()
Private aDocumentsDS As DataSet = New DataSet()
Private aLibraryDS As DataSet = New DataSet()
Private aRolesDS As DataSet = New DataSet()
Private aSettings As mySettings = New mySettings()
Private aUpdateDate As DateTime = DateTime.Now
Private aUser As UserInfo = New UserInfo()
Private aDistributionFilesDS As DataSet = New DataSet()
Public Property UpdateDate() As DateTime
Get
UpdateDate = aUpdateDate
End Get
Set(ByVal Value As DateTime)
aUpdateDate = Value
End Set
End Property
Public Property Settings() As mySettings
Get
Settings = aSettings
End Get
Set(ByVal Value As mySettings)
aSettings = Value
End Set
End Property
Public Property RolesDS() As DataSet
Get
RolesDS = aRolesDS
End Get
Set(ByVal Value As DataSet)
aRolesDS = Value
End Set
End Property
Public Property UserInfo() As UserInfo
Get
UserInfo = aUser
End Get
Set(ByVal Value As UserInfo)
aUser = Value
End Set
End Property
Public Shared Userfolder As String = GetFolderPath(SpecialFolder.ApplicationData) + "\CIM\" + Environment.UserName
Public Shared UserDistributionfolder As String = GetFolderPath(SpecialFolder.ApplicationData) + "\CIM\CIM Distribution Files"
Public Shared Function CheckFile() As Boolean
Return System.IO.File.Exists(Userfolder + "\LocalDB.dat")
End Function
Public Shared Sub Write(ByVal obj As LocalDBObject)
Serializer.Serialize2(obj, Userfolder + "\LocalDB.dat")
End Sub
Public Shared Function Read() As LocalDBObject
If Not System.IO.Directory.Exists(Userfolder) Then
System.IO.Directory.CreateDirectory(Userfolder)
End If
Dim obj As LocalDBObject = Serializer.deSerialize2(Userfolder + "\LocalDB.dat")
Return obj
End Function
Public Property DocumentsDS() As DataSet
Get
DocumentsDS = aDocumentsDS
End Get
Set(ByVal Value As DataSet)
aDocumentsDS = Value
End Set
End Property
Public Property LibraryDS() As DataSet
Get
LibraryDS = aLibraryDS
End Get
Set(ByVal Value As DataSet)
aLibraryDS = Value
End Set
End Property
Public Property OfficesDS() As DataSet
Get
OfficesDS = aOfficesDS
End Get
Set(ByVal Value As DataSet)
aOfficesDS = Value
End Set
End Property
Public Property FieldDS() As DataSet
Get
FieldDS = aFieldDS
End Get
Set(ByVal Value As DataSet)
aFieldDS = Value
End Set
End Property
Public Property SectorsDS() As DataSet
Get
SectorsDS = aSectorsDS
End Get
Set(ByVal Value As DataSet)
aSectorsDS = Value
End Set
End Property
Public Property DistributionDS() As DataSet
Get
DistributionDS = aDistributionFilesDS
End Get
Set(ByVal Value As DataSet)
aDistributionFilesDS = Value
End Set
End Property
Public Shared Function GetNameForLibaryGroup(ByVal FieldID As Integer, ByVal obj As LocalDBObject) As String
For Each dr As DataRow In obj.aFieldDS.Tables(0).Rows
If dr("FieldID") = FieldID Then
Return dr("FieldName")
End If
Next
Return ""
End Function
Public Shared Function GetFileForTemplate(ByVal DocID As Integer) As Byte()
Dim obj As CIMShared.LocalDBObject = CIMShared.LocalDBObject.Read()
For Each dr As DataRow In obj.DocumentsDS.Tables(0).Rows
If dr("docid") = DocID Then
Try
Dim data As Byte() = CType(dr("docdata"), Byte())
Return data
Catch ex As Exception
Return Nothing
End Try
End If
Next
Return Nothing
End Function
Public Shared Function GetFilenameForTemplate(ByVal DocID As Integer) As String
Dim obj As CIMShared.LocalDBObject = CIMShared.LocalDBObject.Read()
For Each dr As DataRow In obj.DocumentsDS.Tables(0).Rows()
If dr("docid") = DocID Then
Return Convert.ToString(LocalDBObject.Userfolder + "\" + dr("docName")) + "_" + Convert.ToString(dr("DocID")) + "." + Convert.ToString(dr("docext")).Substring(1)
End If
Next
Return Guid.NewGuid().ToString().Replace("-", "") + ".txt"
End Function
Public Shared Function GetFilenameOnlyForTemplate(ByVal DocID As Integer) As String
Dim obj As CIMShared.LocalDBObject = CIMShared.LocalDBObject.Read()
For Each dr As DataRow In obj.DocumentsDS.Tables(0).Rows()
If dr("docid") = DocID Then
Return Convert.ToString(dr("docName")) + "." + Convert.ToString(dr("docext")).Substring(1)
End If
Next
Return Guid.NewGuid().ToString().Replace("-", "") + ".txt"
End Function
Public Shared Function GetFilenameForPicture(ByVal DocID As Integer) As String
Dim obj As CIMShared.LocalDBObject = CIMShared.LocalDBObject.Read()
For Each dr As DataRow In obj.DocumentsDS.Tables(0).Rows()
If dr("docid") = DocID Then
Return Convert.ToString(LocalDBObject.Userfolder + "\" + dr("docName")) + "." + Convert.ToString(dr("docext")).Substring(1)
End If
Next
Return Guid.NewGuid().ToString().Replace("-", "") + ".txt"
End Function
Public Shared Function GetFileForLibrary(ByVal DocID As Integer) As Byte()
Dim obj As CIMShared.LocalDBObject = CIMShared.LocalDBObject.Read()
For Each dr As DataRow In obj.LibraryDS.Tables(0).Rows
If dr("docid") = DocID Then
Try
Dim data As Byte() = CType(dr("docdata"), Byte())
Return data
Catch ex As Exception
Return Nothing
End Try
End If
Next
Return Nothing
End Function
Public Shared Function GetFileLibaryDate(ByVal DocID As Integer) As DateTime
Dim obj As CIMShared.LocalDBObject = CIMShared.LocalDBObject.Read()
For Each dr As DataRow In obj.LibraryDS.Tables(0).Rows
If dr("docid") = DocID Then
Try
Dim adate As DateTime = Convert.ToDateTime(dr("docdateupdated"))
Return adate
Catch ex As Exception
Return DateTime.Now.AddYears(-100)
End Try
End If
Next
Return DateTime.Now.AddYears(-100)
End Function
Public Shared Function GetFilenameForLibary(ByVal DocID As Integer) As String
Dim obj As CIMShared.LocalDBObject = CIMShared.LocalDBObject.Read()
For Each dr As DataRow In obj.LibraryDS.Tables(0).Rows
If dr("docid") = DocID Then
Return Convert.ToString(LocalDBObject.Userfolder + "\" + dr("docName")) + "_" + Convert.ToString(dr("DocID")) + "." + Convert.ToString(dr("docext")).Substring(1)
End If
Next
Return Guid.NewGuid().ToString().Replace("-", "") + ".txt"
End Function
'EUGENE: Added this to get the distribution folders.
Public Shared Function GetDistributionFileDS() As List(Of Integer)
Dim LocalDocIDList As New List(Of Integer)
Dim obj As CIMShared.LocalDBObject = CIMShared.LocalDBObject.Read()
If obj.aDistributionFilesDS.Tables.Count > 0 Then
For Each Row As DataRow In obj.aDistributionFilesDS.Tables(0).Rows
LocalDocIDList.Add(Row("docid"))
Next
End If
Return LocalDocIDList
End Function
Public Shared Function GetDistributionFilePath(DocumentID As Integer) As String
Dim LocalDocumentPath As String = ""
Dim obj As CIMShared.LocalDBObject = CIMShared.LocalDBObject.Read()
For Each Row As DataRow In obj.aDistributionFilesDS.Tables(0).Rows
If Row("docid") = DocumentID Then
LocalDocumentPath = LocalDBObject.UserDistributionfolder + "\" + CStr(Row("docid")) + "-" + CStr(Row("docName")) + CStr(Row("docext"))
End If
Next
Return LocalDocumentPath
End Function
Public Shared Function GetDistributionFileData(DocumentID As Integer) As Byte()
Dim LocalDocumentData As Byte() = Nothing
Dim obj As CIMShared.LocalDBObject = CIMShared.LocalDBObject.Read()
For Each Row As DataRow In obj.aDistributionFilesDS.Tables(0).Rows
If Row("docid") = DocumentID Then
LocalDocumentData = CType(Row("docdata"), Byte())
End If
Next
Return LocalDocumentData
End Function
End Class
Here are the serializer functions that serializes the class, and that deserilizes the class.
Public Shared Sub Serialize(ByVal obj As LocalDBObject, ByVal FileName As String)
Dim Stream As New FileStream(FileName, FileMode.OpenOrCreate, FileAccess.Write, FileShare.ReadWrite)
Dim objStreamWriter As New StreamWriter(Stream)
Dim x As New XmlSerializer(obj.GetType)
x.Serialize(objStreamWriter, obj)
objStreamWriter.Close()
End Sub
Public Shared Function deSerialize(ByVal FileName As String) As LocalDBObject
Dim obj As New LocalDBObject()
Dim Stream As FileStream
Dim objStreamReader As StreamReader
Try
Stream = New FileStream(FileName, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)
objStreamReader = New StreamReader(Stream)
Dim x As New XmlSerializer(obj.GetType)
obj = x.Deserialize(objStreamReader)
objStreamReader.Close()
Catch ex As Exception
obj = New LocalDBObject()
Try
Stream.Close()
Catch
End Try
Try
objStreamReader.Close()
Catch
End Try
End Try
Return obj
End Function
NOTE: I realize this is not the cleanest or neatest code, this is a former colleagues code that I am using and trying to resolve bugs on.
What is currently happening is that every time I de-serialize the class, which is about 300MB in size, I get a Out Of Memory Exception. In no way is this using all the computer memory, hence why I would like to find out if there is a memory usage limit on Microsoft Office add-ins?
What object are you talking about? Could you be more specific?
Anyway, I always suggest releasing underlying COM objects insteatly. Use System.Runtime.InteropServices.Marshal.ReleaseComObject to release an Office object when you have finished using it. Then set a variable to Nothing in Visual Basic (null in C#) to release the reference to the object. Read more about that in the Systematically Releasing Objects article.
Related
Trying to fix a warning and not sure how to restructure code as reader.IsClosed is throwing a warning that states "Variable 'reader' is used before it has been assigned a value. A null reference exception could result at run time." Logistically, since reader As SqlDataReader && reader is not initialized with a value then I could ignore as should be fine at runtime, but my inexperience would make me believe there is a better way?
Public Function GetTotalItems(ByVal userId As Long) As Int16
Dim lstParam As List(Of SqlParameter) = New List(Of SqlParameter)()
Dim tablMd = Me.GetMetaData()
Dim retList As ArrayList = New ArrayList()
lstParam.Add(New SqlClient.SqlParameter("#" + tablMd.PrimaryKey.ColumnName, 0))
lstParam.Add(New SqlClient.SqlParameter("#UserID", userId))
lstParam.Add(New SqlClient.SqlParameter("#ActionFlag", "SELECT_ITEMS_COUNT"))
Dim spName As String = Me.GetStoreProcname()
Dim reader As SqlDataReader
Try
reader = SqlHelper.ExecuteReader(
Utility.GetConnectionStringSetting(),
CommandType.StoredProcedure,
Me.GetStoreProcname(),
lstParam.ToArray()
)
If (reader.HasRows = True) Then
If (reader.Read()) Then
Dim value As Object = reader(0)
Return CInt(value)
End If
End If
Catch ex As Exception
Throw
Finally
If Not reader.IsClosed Then
reader.Close()
End If
End Try
Return 0
End Function
We can narrow the problem down to this excerpt:
Dim reader As SqlDataReader
Try
reader = SqlHelper.ExecuteReader( ... )
Finally
If Not reader.IsClosed Then reader.Close()
End Try
The problem comes if an exception is thrown by the ExecuteReader() function. In that event, the reader variable is never assigned a value. It's still Nothing when you try to evaluate reader.IsClosed, and that will cause an exception.
Given you don't actually do anything with the exception and the SqlHelper takes care of the connection and command objects, you can narrow the entire function down to just this:
Public Function GetTotalItems(ByVal userId As Long) As Int16
Dim lstParam = {
New SqlClient.SqlParameter("#" + Me.GetMetaData().PrimaryKey.ColumnName, 0),
New SqlClient.SqlParameter("#UserID", userId),
New SqlClient.SqlParameter("#ActionFlag", "SELECT_ITEMS_COUNT")
}
Using reader As SqlDataReader = SqlHelper.ExecuteReader(
Utility.GetConnectionStringSetting(),
CommandType.StoredProcedure,
Me.GetStoreProcname(),
lstParam)
If reader.Read() Then Return CInt(reader(0))
End Using
Return 0
End Function
#jmcilhinney, #o_O, #Chris Dunaway ... Thank you for the help + appreciation + admiration for your knowledge + reverence == deverence(); ... This removed the error:
Public Function GetTotalAmount(ByVal userId As Long) As Decimal
Dim lstParam As List(Of SqlParameter) = New List(Of SqlParameter)()
Dim tablMd = Me.GetMetaData()
Dim retList As ArrayList = New ArrayList()
lstParam.Add(New SqlClient.SqlParameter("#" + tablMd.PrimaryKey.ColumnName, 0))
lstParam.Add(New SqlClient.SqlParameter("#UserID", userId))
lstParam.Add(New SqlClient.SqlParameter("#ActionFlag", "SELECT_TOTAL_AMOUNT"))
Dim spName As String = Me.GetStoreProcname()
Using reader As SqlDataReader = SqlHelper.ExecuteReader(
Utility.GetConnectionStringSetting(),
CommandType.StoredProcedure,
Me.GetStoreProcname(),
lstParam.ToArray()
)
If (reader.HasRows = True) Then
If (reader.Read()) Then
Dim value As Object = reader(0)
Return CDec(value)
End If
End If
End Using
Return 0
End Function
I have a Public class with a Public Shared Dictionary in vb.net. The constructor does not seem to be running. I have a breakpoint in the constructor which does not break. Also when I make a database update, the new values do not show up in the dictionary.
Public Class SkywalkerPolicy
Public Shared CustomPolicies As Dictionary(Of String, String)
Shared Sub New()
CustomPolicies = New Dictionary(Of String, String)
Dim bvin As String = String.Empty
Dim title As String = String.Empty
Dim poldescr As String = String.Empty
Dim dtResult As New DataTable("Result")
dtResult.Locale = System.Globalization.CultureInfo.InvariantCulture
Dim request As New DataRequest
request.Command = "sky_PolicyDictionary_s"
request.CommandType = CommandType.StoredProcedure
request.Transactional = False
Dim result As DataSet
result = SqlDataHelper.ExecuteDataSet(request)
If Not result Is Nothing Then
If result.Tables.Count() > 0 Then
dtResult = result.Tables(0)
For Each row In dtResult.AsEnumerable
bvin = row.Item(1)
title = row.Item(0)
poldescr = row.Item(2)
If CustomPolicies.ContainsKey(title) Then
CustomPolicies(title) += poldescr
Else
CustomPolicies.Add(title, poldescr)
End If
Next
End If
End If
End Sub
End Class
When I access the dictionary, any changes I've made to the data do not show up.
Dim pol As String = SkywalkerPolicy.CustomPolicies("Orders and Shipping Details")
Does anyone have any suggestions as to how I can get the constructor to work?
Or should I have an additional Sub which duplicates initializing the dictionary before I use it?
Thanks
I have a workaround with an Update routine which I call just before accessing the dictionary. But I am still unclear why I can't step through the constructor. So if anyone can answer the original question, I would appreciate an update. Thank you.
Public Class SkywalkerPolicy
Public Shared CustomPolicies As Dictionary(Of String, String)
Shared Sub New()
CustomPolicies = New Dictionary(Of String, String)
Dim bvin As String = String.Empty
Dim title As String = String.Empty
Dim poldescr As String = String.Empty
Dim dtResult As New DataTable("Result")
dtResult.Locale = System.Globalization.CultureInfo.InvariantCulture
Dim request As New DataRequest
request.Command = "sky_PolicyDictionary_s"
request.CommandType = CommandType.StoredProcedure
request.Transactional = False
Dim result As DataSet
result = SqlDataHelper.ExecuteDataSet(request)
If Not result Is Nothing Then
If result.Tables.Count() > 0 Then
dtResult = result.Tables(0)
For Each row In dtResult.AsEnumerable
bvin = row.Item(1)
title = row.Item(0)
poldescr = row.Item(2)
If CustomPolicies.ContainsKey(title) Then
CustomPolicies(title) += poldescr
Else
CustomPolicies.Add(title, poldescr)
End If
Next
End If
End If
End Sub
Public Shared Sub UpdateDictionary()
CustomPolicies.Clear()
Dim bvin As String = String.Empty
Dim title As String = String.Empty
Dim poldescr As String = String.Empty
Dim dtResult As New DataTable("Result")
dtResult.Locale = System.Globalization.CultureInfo.InvariantCulture
Dim request As New DataRequest
request.Command = "sky_PolicyDictionary_s"
request.CommandType = CommandType.StoredProcedure
request.Transactional = False
Dim result As DataSet
result = SqlDataHelper.ExecuteDataSet(request)
If Not result Is Nothing Then
If result.Tables.Count() > 0 Then
dtResult = result.Tables(0)
For Each row In dtResult.AsEnumerable
bvin = row.Item(1)
title = row.Item(0)
poldescr = row.Item(2)
If CustomPolicies.ContainsKey(title) Then
CustomPolicies(title) += poldescr
Else
CustomPolicies.Add(title, poldescr)
End If
Next
End If
End If
End Sub
End Class
I have functions which serialize and base64 convert objects and vice versa. It uses Newtonsoft to serialize and deserialize Objects. The code works but is there a way to do this without using Newtonsoft?
Public Shared Function SerializeAndBase64(ObjectToSerialize As Object) As ReturnObject(Of String)
Dim rtnObj As New ReturnObject(Of String)
Try
Dim SerializedObjectJson As String = Newtonsoft.Json.JsonConvert.SerializeObject(ObjectToSerialize)
Dim Base64String As String = Convert.ToBase64String(Encoding.UTF8.GetBytes(SerializedObjectJson))
rtnObj.Item = Base64String
Catch ex As Exception
rtnObj.ErrorID = ErrorHandler.handleError(ex)
rtnObj.ErrorMessage = ex.Message
rtnObj.IsError = True
End Try
Return rtnObj
End Function
Public Shared Function DeserializeFromBase64(Of t)(Base64Json As String) As ReturnObject(Of t)
Dim rtnObj As New ReturnObject(Of t)
Try
Dim SerializedObjectJson As String = Encoding.UTF8.GetString(Convert.FromBase64String(Base64Json))
Dim DeserializedObject As t = Newtonsoft.Json.JsonConvert.DeserializeObject(Of t)(SerializedObjectJson)
rtnObj.Item = DeserializedObject
Catch ex As Exception
rtnObj.ErrorID = ErrorHandler.handleError(ex)
rtnObj.ErrorMessage = ex.Message
rtnObj.IsError = True
End Try
Return rtnObj
End Function
Thanks in advance.
You can Serialize/Deserialize it yourself. You just have to come up with a way to save everything into a single string, or XML or even a byte array if you want. Your choice.
Public Class Class1
Public Property MyValue As String
Public Function Serialize() As String
Return MyValue
End Function
Public Sub Deserialize(ByVal value As String)
MyValue = value
End Sub
End Class
I need to return some data from a web service that looks something like this:
data.page = 1
data.count = 12883
data.rows(0).id = 1
data.rows(0).name = "bob"
data.rows(1).id = 2
data.rows(1).name = "steve"
data.rows(2).id = 3
data.rows(2).name = "fred"
I have no idea how to do this. I've returend simple types and simple arrays, but never an object like this.
The data source is a sql Database. The target is a javascript/ajax function. I'm currently successfully returning the rows themselves as a dataset and it works, but I need to add the count and a couple other "parent level" variables.
For the sake of full disclosure, here is the code that is working:
<WebMethod()> _
Public Function rptPendingServerRequests() As DataSet
Dim connetionString As String
Dim connection As SqlConnection
Dim command As SqlCommand
Dim adapter As New SqlDataAdapter
Dim ds As New DataSet
Dim sql As String
connetionString = "..."
sql = "SELECT usm_request.request_id, usm_request.status, usm_request.req_by_user_id " +
"FROM usm_request " +
"WHERE usm_request.request_id in " +
"(SELECT distinct(usm_request.request_id) from usm_request, usm_subscription_detail WHERE usm_request.request_id = usm_subscription_detail.request_id " +
"AND usm_subscription_detail.offering_id = 10307) ORDER BY usm_request.request_id DESC"
connection = New SqlConnection(connetionString)
Try
connection.Open()
command = New SqlCommand(sql, connection)
adapter.SelectCommand = command
adapter.Fill(ds)
adapter.Dispose()
command.Dispose()
connection.Close()
Return ds
Catch ex As Exception
End Try
End Function
And I'm trying to consume it with FlexiGrid. I've been working at it for a few hours with no luck. I basically need to convert the PHP at the following site to .net
http://code.google.com/p/flexigrid/wiki/TutorialPropertiesAndDocumentation
I think that you would be much better off just creating a couple of classes and moving the data from the database into these classes. For example:
Public Class MyDataClass
Public Property Page As Integer
Public ReadOnly Property Count As Integer
Get
If Me.Rows IsNot Nothing Then
Return Me.Rows.Count
Else
Return 0
End If
End Get
End Property
Public Property Rows As List(Of MyDataRow)
' Parameterless constructor to support serialization.
Public Sub New()
Me.Rows = New List(Of MyDataRow)
End Sub
Public Sub New(wPage As Integer, ds As DataSet)
Me.New()
Me.Page = wPage
For Each oRow As DataRow In ds.Tables(0).Rows
Dim oMyRow As New MyDataRow
oMyRow.Id = oRow("id")
oMyRow.Name = oRow("Name")
Me.Rows.Add(oMyRow)
Next
End Sub
End Class
Public Class MyDataRow
Public Property Id As Integer
Public Property Name As String
' Parameterless constructor to support serialization
Public Sub New()
End Sub
End Class
Then change the return type of the method to MyDataClass and change the return to:
Return New MyDataClass(1, ds)
I've recently been updating a lot of my code to comply with proper n-tier architecture and OO programming, following examples from a book.
I'm starting to get problems now because I don't fully understand the access modifiers.
If I run the following code I get an error at the line
Dim clientFamilyDataAccessLayer As New ClientFamilyDAO
in the BLL at the point it creates an instance of the DAL. The full error message is: "The type initializer for 'ClientFamilyDAO' threw an exception. ---> System.NullReferenceException: Object reference not set to an instance of an object."
How do I use these function to create a list of ClientFamily objects that I can then work with?
On my UI layer I'm creating a list of objects; ClientFamilies
Dim listOfClientFamilies As List(Of ClientFamily) = ClientFamily.GetClientFamiliesByKRM(selectedEmployee.StaffNumber)
This is the function in the BLL
Public Shared Function GetClientFamiliesByKRM(ByVal krmStaffNumber As Integer) As List(Of ClientFamily)
Dim clientFamilyDataAccessLayer As New ClientFamilyDAO
Return clientFamilyDataAccessLayer.GetClientFamiliesByKRM(krmStaffNumber)
End Function
and this is function in the DAL
Public Function GetClientFamiliesByKRM(ByVal staffNumber As Integer) As List(Of ClientFamily)
Dim currentConnection As SqlConnection = New SqlConnection(_connectionString)
Dim currentCommand As New SqlCommand
currentCommand.CommandText = mainSelectStatement & " WHERE Key_Relationship_Manager = #StaffNumber ORDER BY Client_Family_Name"
currentCommand.Parameters.AddWithValue("#StaffNumber", staffNumber)
currentCommand.Connection = currentConnection
Dim listOfClientFamilies As New List(Of ClientFamily)
Using currentConnection
currentConnection.Open()
Dim currentDataReader As SqlDataReader = currentCommand.ExecuteReader()
Do While currentDataReader.Read
Dim newClientFamily As AECOM.ClientFamily = PopulateClientFamily(currentDataReader)
listOfClientFamilies.Add(newClientFamily)
Loop
End Using
Return listOfClientFamilies
End Function
Here's the full ClientFamilyDAO Class:
Public Class ClientFamilyDAO
Private Const mainSelectStatement As String = "SELECT Client_Family_ID, Client_Family_Name, Key_Relationship_Organisation, Key_Relationship_Manager, Obsolete, Market_Sector_ID FROM Client_Families"
Private Shared ReadOnly _connectionString As String = String.Empty
Shared Sub New()
_connectionString = WebConfigurationManager.ConnectionStrings("ClientFamilyManagementConnectionString").ConnectionString
End Sub
Public Function GetClientFamiliesByKRM(ByVal staffNumber As Integer) As List(Of ClientFamily)
Dim currentConnection As SqlConnection = New SqlConnection(_connectionString)
Dim currentCommand As New SqlCommand
currentCommand.CommandText = mainSelectStatement & " WHERE Key_Relationship_Manager = #StaffNumber ORDER BY Client_Family_Name"
currentCommand.Parameters.AddWithValue("#StaffNumber", staffNumber)
currentCommand.Connection = currentConnection
Dim listOfClientFamilies As New List(Of ClientFamily)
Using currentConnection
currentConnection.Open()
Dim currentDataReader As SqlDataReader = currentCommand.ExecuteReader()
Do While currentDataReader.Read
Dim newClientFamily As AECOM.ClientFamily = PopulateClientFamily(currentDataReader)
listOfClientFamilies.Add(newClientFamily)
Loop
End Using
Return listOfClientFamilies
End Function
Private Function PopulateClientFamily(ByVal currentDataReader As SqlDataReader) As AECOM.ClientFamily
Dim newClientFamily As New AECOM.ClientFamily
If Not (currentDataReader.IsDBNull(currentDataReader.GetOrdinal("Client_Family_ID"))) Then
newClientFamily.ClientFamilyID = currentDataReader("Client_Family_ID")
End If
If Not (currentDataReader.IsDBNull(currentDataReader.GetOrdinal("Client_Family_Name"))) Then
newClientFamily.ClientFamilyName = currentDataReader("Client_Family_Name")
End If
If Not (currentDataReader.IsDBNull(currentDataReader.GetOrdinal("Key_Relationship_Organisation"))) Then
Select Case currentDataReader("Key_Relationship_Organisation")
Case False
newClientFamily.IsKeyRelationshipOrganisation = False
Case True
newClientFamily.IsKeyRelationshipOrganisation = True
End Select
End If
If Not (currentDataReader.IsDBNull(currentDataReader.GetOrdinal("Key_Relationship_Manager"))) Then
newClientFamily.KeyRelationshipManagerStaffNumber = currentDataReader("Key_Relationship_Manager")
End If
If Not (currentDataReader.IsDBNull(currentDataReader.GetOrdinal("Obsolete"))) Then
Select Case currentDataReader("Obsolete")
Case False
newClientFamily.Obsolete = False
Case True
newClientFamily.Obsolete = True
End Select
End If
If Not (currentDataReader.IsDBNull(currentDataReader.GetOrdinal("Market_Sector_ID"))) Then
newClientFamily.MarketSectorID = currentDataReader("Market_Sector_ID")
End If
Return newClientFamily
End Function
End Class
The issue doesn't relate to access modifiers, rather it is more to do with the exception message you get. The following line within the constructor of ClientFamilyDAO would seem to be causing the issue:
_connectionString = WebConfigurationManager.ConnectionStrings("ClientFamilyManagementConnectionString").ConnectionString
Are you sure ClientFamilyManagementConnectionString exists in the configuration?