2015-11-04 30 views
1

我試圖使用My.Settings來保存經過身份驗證的服務器及其信息的列表,但我無法弄清楚如何製作自定義類型。VB.Net My.Settings保存的SQL服務器列表的自定義類型

我有一個類,現在叫SqlServer的具有這三個領域:

Public ServerName As String 
Public UserName As String 
Public Password As String 

每次我使用SQL身份驗證連接到SQL服務器,我想保存服務器和登錄信息。這意味着我需要一個自定義類型,它是My.Settings中SqlServer的集合。

這是我到目前爲止的代碼:

Public Class SQLServerList 
    Inherits List(Of SQLServer) 
    Implements IComparable(Of SQLServer) 

    Public Function CompareTo(ByVal SqlServerInfo As SQLServer) As Integer Implements IComparable(Of MyProjectName.SQLServer).CompareTo 
    ... 
    End Function 
End Class 

我在正確的軌道上通過繼承列表?我需要什麼類型的屬性/字段才能讓這個東西按我想要的那樣工作?謝謝。

+0

你可能會更好地序列化你的集合類。如[存儲對象集合](http://stackoverflow.com/q/25879442/1070452)。就我個人而言,我會讓'SQLServerList'成爲*實現的集合類* a:列表 Plutonix

+0

好吧,這就是我現在所擁有的:公共類SqlServerList繼承集合(SqlServer)實現IList(Of SqlServer)..我是很確定這就是你在 – cjw

+0

得到的,如果你繼承'Collection(Of T)',你不需要列表。我實現List(T)的意思是一個簡單的'Private myList(Of SQLServer)'。你的類會公開Add等方法來管理列表。該類可以有一個Save方法來完成序列化(2-3行代碼)和一個Shared方法來加載它們。儘管收集將完全工作。 – Plutonix

回答

2

給定一個集合類,它很容易讓它序列化內容本身。

Imports System.IO 
Imports System.Runtime.Serialization.Formatters.Binary 

<Serializable> 
Public Class Server 
    Public Property Name As String 
    Public Property UserName As String 
    Public Property Password As String 
End Class 

一個簡單的集合類:

<Serializable> 
Public Class Servers 
    Private myList As List(Of Server) 

    Public Sub New() 
     myList = New List(Of Server) 
    End Sub 

    Public Sub Add(svr As Server) 
     myList.Add(svr) 
    End Sub 

    ' no reason it cant also create server objects for you 
    Public Sub Add(sname As String, uname As String, pw As String) 
     myList.Add(New Server With {.Name = sname, .UserName = uname, .Password = pw}) 
    End Sub 

    'toDo Contains, Count, Item etc as needed 

    Public Sub Save(mypath As String) 
     Using fs As New FileStream(mypath, FileMode.OpenOrCreate) 
      Dim bf As New BinaryFormatter 
      bf.Serialize(fs, myList) 
     End Using 
    End Sub 

    Public Function Load(mypath As String) As Int32 
     'ToDo: check if file exists 
     Using fs As New FileStream(mypath, FileMode.Open) 
      Dim bf As New BinaryFormatter 
      myList = CType(bf.Deserialize(fs), List(Of Server)) 
     End Using 

     If myList IsNot Nothing Then 
      Return myList.Count 
     Else 
      Return 0 
     End If 
    End Function 
End Class 

<Serializable>屬性是必需的BinaryFormatter。不同的序列化程序(json,ProtoBuf-NET)可能有自己的。

「魔術」在SaveLoad方法序列化或反序列化對象的內部列表。只需幾行代碼即可加載/保存1或1000個項目。它是一個很好的替代數據庫的少量數據。

測試對於往返:

Dim svrs As New Servers 
    svrs.Add("SqlSS1", "ziggy", "foo") 
    svrs.Add("SqlSS2", "zacky", "bar") 
    svrs.Add("SqlSS3", "zoey", "baz") 

    svrs.Save("C:\Temp\SSvrs.bin") 

    ' now load to a new Servers collection 
    ' to test the round trip 
    Dim svrs2 As New Servers 
    Dim sCount = svrs2.Load("C:\Temp\SSvrs.bin") 

    For n = 0 To sCount - 1 
     Console.WriteLine("{0} {1} {2} ", svrs2(n).Name, svrs2(n).UserName, svrs2(n).Password) 
    Next 

輸出:

SqlSS1齊格FOO
SqlSS2 zacky酒吧
SqlSS3柔依巴茲

我使用的BinaryFormatter(對於無真正的原因),但ProtoBuf-NET或XMLSerializer也會工作。由於數據全部是字符串,因此您可能需要對它們進行加密(將文件流包裝在密碼流中)。

1

如果您想要將您定義的一些類保存到My.Settings中,您基本上需要滿足與任何XML可序列化類相同的要求。

  • 你的類必須是可串行化的。
  • 你的類必須有一個不帶參數的公共默認構造函數。
  • 您的.NET類中的任何屬性必須是可串行化的。
  • 你班上的任何班級都必須符合這些相同的要求。
0

基準測試,序列化對象binaryfile,XML文件和XML字符串:

  • 收件500.000對象binaryfile(1954ms/23MB)
  • 收件500.000對象的XML文件(660ms/46MB)
  • 收件500.000對象XML字符串(847ms,處理38MB-> 348MB)

驚訝地發現它需要更長的時間來寫一個二進制文件比XML文件。我希望.Net只是轉儲內存而不進行任何處理和轉換。也許有比使用的更好的二進制串行器?

儘管預計會更小。 XML文件「僅」具有100%的開銷。

看到寫入XML文件比寫入內存中的字符串還要快。

我相信我的代碼可以被優化,這是很奇怪的,隨時要進行序列化:-)貢獻

對象:

<Serializable> _ 
Public Class oNames 
    Public Shared cNames As New List(Of oName) 

    <Serializable> _ 
    Public Class oName 
     Public Property Firstname As String 
     Public Property Lastname As String 
     Sub New() 
     End Sub 
    End Class 

    Sub New() 
    End Sub 
End Class 

填充列表與500.000對象:

oNames.cNames.Clear() 
For i As Integer = 1 To 500000 
    oNames.cNames.Add(New oNames.oName With {.Firstname = "MyFirstName" & i.ToString, .Lastname = "MyLastName" & i.ToString}) 
Next 

寫入二進制文件(使用我自己的串行器類):

WCC.BinSerialization.ToFile(oNames.cNames, "c:\temp\ObjToBin.bin", IO.FileMode.Append) 

寫入XML文件(用我自己的序列化器類):

WCC.XMLSerialization.Obj_To_XMLFile(oNames.cNames, "c:\temp\ObjToXML.xml") 

寫入XML字符串(用我自己的序列化器類):

Dim XMLStr As String 
XMLStr = WCC.XMLSerialization.Obj_To_XLMStr(oNames.cNames) 

我的串行器類:

Public Class WCC 
    Public Class XMLSerialization 

     Public Shared Function Obj_To_XLMStr(Obj As Object) As String 
      Using SW As New System.IO.StringWriter 
       Dim X As New System.Xml.Serialization.XmlSerializer(Obj.GetType) 
       X.Serialize(SW, Obj) 
       Return SW.ToString 
      End Using 
     End Function 

     Public Shared Sub XMLStr_To_Obj(XMLString As String, ByRef ListObj As Object) 
      Using SR As New System.IO.StringReader(XMLString) 
       Dim X As New System.Xml.Serialization.XmlSerializer(ListObj.GetType) 
       ListObj = X.Deserialize(SR) 
      End Using 
     End Sub 

     Public Shared Sub Obj_To_XMLFile(Obj As Object, Path As String) 
      Dim XWS As New System.Xml.XmlWriterSettings 
      XWS.Indent = True 
      XWS.IndentChars = vbTab 
      Using XW As System.Xml.XmlWriter = System.Xml.XmlWriter.Create(Path, XWS) 
       Dim X As New System.Xml.Serialization.XmlSerializer(Obj.GetType) 
       X.Serialize(XW, Obj) 
      End Using 
     End Sub 
    End Class 

    Public Class BinSerialization 
     Public Shared Sub ToFile(Obj As Object, Path As String, FileMode As IO.FileMode) 
      Using fs As New System.IO.FileStream(Path, FileMode) 
       Dim bf As New System.Runtime.Serialization.Formatters.Binary.BinaryFormatter 
       bf.Serialize(fs, Obj) 
      End Using 
     End Sub 
    End Class 
End Class 
+0

看來。網BinaryFormatter只表現非常糟糕。 它只是嘗試了第三部分protobuf網類 寫500.000到二進制文件:717ms 從二進制文件讀取500.000:1102ms和文件大小18.3MB – MrCalvin