65.9K
CodeProject 正在变化。 阅读更多。
Home

使用快速简便的可保存对象类、JSON 和 LINQ 的简单博客

starIconstarIcon
emptyStarIcon
starIcon
emptyStarIconemptyStarIcon

2.78/5 (3投票s)

2007年12月8日

CPOL

2分钟阅读

viewsIcon

20527

downloadIcon

141

学习如何创建自动保存和检索其数据的类(),以及如何使用 LINQ 快速查询这些数据。我的类 `Saveable` 的示例实现展示了创建博客是多么容易。

Screenshot of Blog implementation

引言

你是否曾经创建了一个出色的类,然后不得不编写子例程来保存和检索它?太痛苦了。我对此感到厌倦,所以创建了 `Saveable` 类。你可以通过继承来扩展任何你编写的类。

它使用 JSON(JavaScript 对象表示法)序列化(现在内置于 .NET Framework 3.5 和 Visual Studio 2008 中)来迭代类的成员,检索数据并将其保存到文件中。

等等!?你用 JSON 作为数据库!? 是的,没错。JSON 序列化比 XML 序列化更快,创建的文件更小,同时仍然保持人类可读性。我知道这并非 JSON 的原始目的,但它有效,而且效果非常好

我包含的示例实现是一个博客引擎。警告:它非常简单,只是为了展示 `Saveable(Of T)` 的特性。在将其投入实际使用之前,它需要进行大量的改进。但它包含用于管理帖子和评论的代码。它还包含使用 `RegularExpression` 和 `LINQ` 对帖子执行排序搜索的代码。

Using the Code

我的 `Saveable` 类的核心是两个方法:`ToJSON` 和 `FromJSON`

Shared Serializer As New Runtime.Serialization.Json.DataContractJsonSerializer(GetType(T))
    Public Shared Function ToJSON(ByVal Obj As Object) As String
        Dim tt As New IO.MemoryStream
        Serializer.WriteObject(tt, Obj)
        tt.Close()
        Return System.Text.Encoding.ASCII.GetString(tt.ToArray)
    End Function

    Public Shared Function FromJSON(ByVal Data As String, ByVal Type As Type) As Object
        If String.IsNullOrEmpty(Data) Then Return Nothing
        Dim tt As New IO.MemoryStream(System.Text.Encoding.ASCII.GetBytes(Data))
        Return Serializer.ReadObject(tt)
    End Function

这些方法将你的对象转换为和从文本转换。

要开始使用该类,请创建你自己的类,该类继承自 `Saveable(Of T)`,其中 `T` 是你的类的类型。然后导入 `System.Runtime.Serialization` 并添加 `DataContract` 属性。

Imports System.Runtime.Serialization

 Public Class BlogMessage : Inherits Saveable(Of BlogMessage)

End Class

接下来,添加你的类需要的任何属性。`Saveable(Of T)` 类已经包含用于 `ID as GUID`、`DateCreated as Date` 和 `DateModified as Date` 的属性。

Imports System.Runtime.Serialization

<DataContract()> Public Class BlogMessage : Inherits Saveable(Of BlogMessage)
    Dim _Title As String
    <DataMember()> Public Property Title() As String
        Get
            Return _Title
        End Get
        Set(ByVal value As String)
            _Title = value
        End Set
    End Property

    Dim _message As String
    <DataMember()> Public Property Message() As String
        Get
            Return _message
        End Get
        Set(ByVal value As String)
            _message = value
        End Set
    End Property
End Class

现在,你可以做一些很酷的事情了

'Create a New One



Dim b as New BlogMessage With { .Title = "My New Post!", _
        .Message = "This is the content for the post." }
b.Save()

`Save()` 方法会在必要时创建一个新的 `ID`,如果为空则设置 `DateCreated`,更新 `DateUpdated`,将对象序列化为文本,并将其保存到以 ID 命名的 *.js 文件中——位于以对象命名的文件夹下(在本例中为 `BlogMessage`)在 *App_Data* 文件夹下(即 *~/App_Data/BlogMessage/42dc0fb5-c516-4536-b273-6bbff8ed33ae.js*)。

将对象加载回内存同样容易

'Load an Old One



Dim b as BlogMessage = BlogMessage.Load("42dc0fb5-c516-4536-b273-6bbff8ed33ae")
'Now do something with it



Response.Write(b.Message)

现在,将你的类提升到一个新的水平。我添加了另一个类 `BlogComment`,它也继承自 `Saveable(Of T)`。然后我添加了一些 LINQ(顺便说一句,它真的太棒了)

Imports System.Runtime.Serialization
Imports System.Linq

<DataContract()> Public Class BlogMessage : Inherits Saveable(Of BlogMessage)
    <DataMember(Name:="Comments")> Dim _comments As Generic.Dictionary_
            (Of Guid, BlogComment)
    Public ReadOnly Property Comments() As Generic.Dictionary(Of Guid, BlogComment)
        Get
            If _comments Is Nothing Then _comments = _
                    New Generic.Dictionary(Of Guid, BlogComment)
            Return _comments
        End Get
    End Property

    Dim _Title As String
    <DataMember()> Public Property Title() As String
        Get
            Return _Title
        End Get
        Set(ByVal value As String)
            _Title = value
        End Set
    End Property

    Dim _message As String
    <DataMember()> Public Property Message() As String
        Get
            Return _message
        End Get
        Set(ByVal value As String)
            _message = value
        End Set
    End Property

    Public Shared Function GetPostByTitle(ByVal Title As String) As BlogMessage
        Dim o As Generic.IEnumerable(Of BlogMessage) = From b As BlogMessage In _
            BlogMessage.GetAll Where b.Title.Equals_
            (Title, StringComparison.OrdinalIgnoreCase) Take 1
        If o.Count = 0 Then Return Nothing
        Return o.First
    End Function

    Public Shared Function Search(ByVal Terms As String) As BlogMessage()
        Dim r As New Regex("(" & Terms.Trim.Replace(" ", ")|(") & ")", _
            RegexOptions.Singleline Or RegexOptions.IgnoreCase Or _
            RegexOptions.Compiled)
        Return (From b As BlogMessage In BlogMessage.GetAll Select b, k = _
            b.Rank(r) Where k >= 0 Order By k Descending Select b).ToArray
    End Function

    Private Function Rank(ByVal r As Regex) As Double
        Dim c As String = Title & vbNewLine & Message
        Dim m As MatchCollection = r.Matches(c)
        If m.Count = 0 Then Return -1
        Return Aggregate dm As Match In m Into Sum(dm.Index / c.Length)
    End Function
End Class

关注点

JSON 和 LINQ 很酷!
待办事项:学习更多 LINQ!它很棒,而且功能强大。请查看这里的示例 here

© . All rights reserved.