分享
 
 
 

基于动态数据库的三层体系

王朝other·作者佚名  2006-01-10
窄屏简体版  字體: |||超大  

本来通宇的项目都要做完了,可是今天公司的老板忽然又提出了新的要求,说要实现完全地动态建库,连一开始的总的完全表都没有,这就使得我们的整个项目的体系都要改。再前面的文章中,我曾经写过项目本来的架构,那个架构是基于一个固定的完全表的,然后以后再从完全表中选出字段来进行动态建库。

搞得我们所有人都非常郁闷,不过也没办法,还是要改。我考虑了一下,觉得也还是可以做的,可以封装好,实现三层架构。思路是利用arraylist 和hashtable来实现参数传递。

架构分为Data 实现具体的数据库操作

EntityClass 对增加删除等操作的封装

Business 业务逻辑处理层,用户可以自行添加代码

WinForm 显示界面

一、Data

Data有两个文件,ConnectionFactory.vb和DataFactory.vb

ConnectionFactory.vb实现连接数据库,代码如下

Imports System

Imports System.Data

Imports System.Data.SqlClient

Namespace Data

Public Class ConnectionFactory

Private Const ConnectionKey As String = "ConnectionString"

Public Sub New()

' TODO: 在此处添加构造函数逻辑

End Sub

Public Shared Function myConnection() As System.Data.SqlClient.SqlConnection

Dim cmConn As New SqlConnection

Dim strConnection As String = System.Configuration.ConfigurationSettings.GetConfig(ConnectionKey)

strConnection = "server=200.200.200.101;database=TYTK;user id=sa;password=sa"

If strConnection <> " " Then

cmConn.ConnectionString = strConnection

Return cmConn

Else

'应该返回null

cmConn.Close()

Return cmConn

End If

End Function

Public Shared Function myConnection(ByVal strConnection As String) As System.Data.SqlClient.SqlConnection

Dim ConnectionKey1 As String

If strConnection <> " " Then

ConnectionKey1 = strConnection

End If

Dim cmConn As SqlConnection = New SqlConnection

strConnection = System.Configuration.ConfigurationSettings.GetConfig(ConnectionKey1)

If (strConnection <> "") Then

cmConn.ConnectionString = strConnection

Return cmConn

Else

cmConn.Close()

Return cmConn

End If

End Function

End Class

End Namespace

DataFactory.vb 实现数据库的底层操作,代码如下

Imports System

Imports System.Data

Imports System.Data.SqlClient

Namespace Data

Public Class DataFactory

Protected myCommand As SqlCommand

Protected myTrans As SqlTransaction

Protected strErrMessage As String

Protected myConnection As SqlConnection

Protected myDataAdapter As SqlDataAdapter

Protected thisTransactionOn As Boolean

Public Sub New()

' TODO: 在此处添加构造函数逻辑

Me.myConnection = ConnectionFactory.myConnection()

' this.myCommand = this.myConnection.CreateCommand();

' this.myDataAdapter = new SqlDataAdapter(this.myCommand);

'MsgBox("hehe" + Me.myConnection.Database.ToString)

Me.strErrMessage = ""

Me.thisTransactionOn = False

'新增了一个初始化()

Me.myCommand = New SqlClient.SqlCommand

End Sub

'设置SQL语句

Protected Function SetCommandText(ByVal commandText As String, ByVal commandType As CommandType)

'MsgBox(Me.myCommand.CommandText)

'MsgBox(Me.thisTransactionOn)

If (Me.thisTransactionOn) Then

'MsgBox(5)

If (Me.myCommand.ToString.Equals("")) Then

Me.myCommand = Me.myConnection.CreateCommand()

Me.myCommand.Transaction = Me.myTrans

ElseIf (Me.myCommand.Connection.State = ConnectionState.Closed) Then

Me.myCommand.Connection = Me.myConnection

Me.myCommand.Transaction = Me.myTrans

End If

ElseIf ((Not Me.thisTransactionOn) And Me.myCommand.CommandText.Equals("")) Then

'MsgBox(6)

Me.myCommand = Me.myConnection.CreateCommand()

End If

Me.myDataAdapter = New SqlDataAdapter(Me.myCommand)

Me.myCommand.CommandText = commandText

Me.myCommand.CommandType = commandType

End Function

Protected Function SetCommandText(ByVal commandText As String)

Me.myCommand.CommandText = commandText

End Function

'下面还有各种增加删除等

'ddddddd

Private Function ChackTransAndConnect() As Boolean

If (Me.thisTransactionOn) Then

If (Me.myConnection.State = ConnectionState.Closed) Then

' this.strErrMessage = "事务连接已断开"

' this.CloseTransation()

Try

Me.myConnection = Me.myTrans.Connection

Catch

Return False

End Try

End If

Else

If (Me.myConnection.State = ConnectionState.Closed) Then

Me.myConnection.Open()

End If

End If

Return True

End Function

'执行一条Sql指令,返回一张内存表

Public Function DataTableResult(ByVal _strSql As String) As DataTable

Dim tempDataTable As New DataTable

Try

If (Not Me.ChackTransAndConnect()) Then

Return tempDataTable

End If

'MsgBox(_strSql)

'MsgBox(System.Data.CommandType.Text)

Me.SetCommandText(_strSql, System.Data.CommandType.Text)

'MsgBox(tempDataTable.ToString)

Me.myDataAdapter.Fill(tempDataTable)

Catch e As SqlException

strErrMessage = "获取数据表出现未知异常。" + e.Message

Throw

Catch ex As Exception

strErrMessage = ex.Message

Throw

Finally

Me.myCommand.Parameters.Clear()

If (Not Me.thisTransactionOn) Then

If (Me.myConnection.State = ConnectionState.Open) Then

Me.myConnection.Close()

End If

End If

End Try

Return tempDataTable

End Function

' 读取表中某列的一条记录

Public Function ReadOneLog(ByVal _strSql As String) As Object

Dim sResult As New Object

Try

If (Not Me.ChackTransAndConnect()) Then

Return Nothing

End If

Me.SetCommandText(_strSql, System.Data.CommandType.Text)

Dim myReader As SqlDataReader = Me.myCommand.ExecuteReader()

If (myReader.Read()) Then

sResult = myReader.GetValue(0)

End If

myReader.Close()

Catch e As SqlException

strErrMessage = "执行命令出现SQL异常。" + e.Message

Throw

Catch

strErrMessage = "执行命令出现未知异常。"

Throw

Finally

If (Not Me.thisTransactionOn) Then

If (Me.myConnection.State = ConnectionState.Open) Then

Me.myConnection.Close()

End If

End If

End Try

Return sResult

End Function

' 执行命令并返回受影响的行数

Public Function ExecuteNonQuery(ByVal _strSql As String) As Integer

Dim tempExecuteNonQueryResult As Integer = 0

Try

If (Not Me.ChackTransAndConnect()) Then

Return 0

End If

Me.SetCommandText(_strSql, System.Data.CommandType.Text)

tempExecuteNonQueryResult = Me.myCommand.ExecuteNonQuery()

Catch e As SqlException

strErrMessage = "执行命令出现SQL异常。" + e.Message

Throw

Catch ex As Exception

strErrMessage = ex.Message

Throw

Finally

Me.myCommand.Parameters.Clear()

Me.myCommand.Dispose()

If (Not Me.thisTransactionOn) Then

If (Me.myConnection.State = ConnectionState.Open) Then

Me.myConnection.Close()

End If

End If

End Try

Return tempExecuteNonQueryResult

End Function

Public Sub AddCommandParameter(ByVal Parameters As SqlParameter)

Me.myCommand.Parameters.Add(Parameters)

End Sub

' '向Command添加参数

'</summary>

' <param name="ParameterName">参数名</param>

'<param name="Type">数据类型</param>

' <param name="Value">参数值</param>

' <returns></returns>

Public Sub AddCommandParameter(ByVal ParameterName As String, ByVal Type As System.Data.SqlDbType, ByVal Value As Object)

Dim Parameters As SqlParameter = New SqlParameter

Parameters.ParameterName = ParameterName

Parameters.SqlDbType = Type

Parameters.Value = Value

Me.myCommand.Parameters.Add(Parameters)

End Sub

' <summary>

' 打开事务

' </summary>

Public Function BeginTransation() As Boolean

If Me.thisTransactionOn Then

Me.strErrMessage = "当前已有打开的事务"

Return False

If Me.myConnection.State = ConnectionState.Closed Then

Me.myConnection.Open()

Me.myTrans = Me.myConnection.BeginTransaction()

Me.myCommand = Me.myConnection.CreateCommand()

Me.myCommand.Transaction = Me.myTrans

Me.thisTransactionOn = True

Return True

Else

Me.strErrMessage = "当前有未关闭的连接"

Return False

' <summary>

' 结束事务

' </summary>

End If

End If

End Function

Public Sub CloseTransation()

If Not Me.thisTransactionOn Then

Me.strErrMessage = "当前没有打开的事务"

If Me.myConnection.State = ConnectionState.Open Then

Me.myConnection.Close()

Me.myTrans.Dispose()

Me.thisTransactionOn = False

End If

End If

End Sub

' <summary>

' 回滚事务

'</summary>

Public Function Rollback() As Boolean

If Not Me.thisTransactionOn Then

Me.strErrMessage = "事务尚未打开"

Return False

Try

Me.myTrans.Commit()

' this.myCommand.Transaction.Rollback();

' this.myCommand.Transaction = null;

If Me.myConnection.State = ConnectionState.Open Then

Me.myConnection.Close()

End If

Catch ex As Exception

strErrMessage = "回滚事务失败:" + ex.Message

Return False

Finally

Me.CloseTransation()

End Try

End If

Return True

End Function

'<summary>

'提交事务

'</summary>

Public Function Commit() As Boolean

If Not Me.thisTransactionOn Then

Me.strErrMessage = "事务尚未打开"

Return False

Try

Me.myTrans.Commit()

' me.myCommand.Transaction.Commit()

' this.myCommand.Transaction = null

If Me.myConnection.State = ConnectionState.Open Then

Me.myConnection.Close()

End If

Catch ex As Exception

strErrMessage = "提交事务失败:" + ex.Message

Return False

Finally

Me.CloseTransation()

End Try

Return True

End If

' <summary>

' 根据事务状态决定是否打开连接,并判断操作是否可以继续

' </summary>

' <returns>true表示可以继续执行,false表示错误,中断操作</returns>

End Function

' <summary>

'执行命令并返回受影响的行数

' </summary>

'<returns>受影响的行数</returns>

Public Function ExecuteNonQuery(ByVal _strSql As String, ByVal Parameters As SqlParameter) As Integer

Dim tempExecuteNonQueryResult As Integer = 0

Try

If Not Me.ChackTransAndConnect() Then

Return 0

End If

Me.SetCommandText(_strSql, System.Data.CommandType.Text)

Me.AddCommandParameter(Parameters)

tempExecuteNonQueryResult = Me.myCommand.ExecuteNonQuery()

Catch e As Exception

strErrMessage = "执行命令出现SQL异常。" + e.Message

Throw

Catch

strErrMessage = "执行命令出现未知异常。"

Throw

Finally

Me.myCommand.Parameters.Clear()

If Not Me.thisTransactionOn Then

If Me.myConnection.State = ConnectionState.Open Then

Me.myConnection.Close()

End If

End If

End Try

Return tempExecuteNonQueryResult

End Function

'<summary>

' 执行命令并返回最大流水号

' </summary>

'<returns>最大流水号,-1表示执行错误</returns>

Public Function ExecuteOnReader(ByVal _strSql As String) As Integer

Dim tempExecuteReaderResult As Integer = -1

Try

If Not Me.ChackTransAndConnect() Then

Return tempExecuteReaderResult

End If

Me.SetCommandText(_strSql, System.Data.CommandType.Text)

Dim myreader As SqlDataReader = Me.myCommand.ExecuteReader()

If myReader.Read() Then

tempExecuteReaderResult = Convert.ToInt32(myreader.GetValue(0))

End If

Catch e As SqlException

strErrMessage = "执行命令出现SQL异常。" + e.Message

Throw

Catch ex As Exception

strErrMessage = ex.Message

Throw

Finally

Me.myCommand.Parameters.Clear()

If Not Me.thisTransactionOn Then

If Me.myConnection.State = ConnectionState.Open Then

Me.myConnection.Close()

End If

End If

End Try

Return tempExecuteReaderResult

End Function

' <summary>

' 填充Dataset

' </summary>

' <param name="dataset"></param>

' <param name="connection"></param>

' <param name="query"></param>

' <returns></returns>

Public Sub SelectSqlSrvRows(ByVal dataset As DataSet, ByVal query As String)

Try

If Not Me.ChackTransAndConnect() Then

Return

End If

Me.SetCommandText(query, System.Data.CommandType.Text)

Me.myDataAdapter.Fill(dataset)

Catch e As SqlException

strErrMessage = "获取数据表出现未知异常。" + e.Message

Throw

Catch

strErrMessage = "获取数据表出现未知异常。"

Throw

Finally

Me.myCommand.Parameters.Clear()

If Not Me.thisTransactionOn Then

If Me.myConnection.State = ConnectionState.Open Then

Me.myConnection.Close()

End If

End If

End Try

End Sub

' public SqlConnection ConnectionObj

' {

' set

'' {

' me.myConnection = value;

' }

' get

' {

' return me.myConnection;

' }

' }

Public Function set_TransStatus(ByVal value As Boolean) As Boolean

Me.thisTransactionOn = value

End Function

Public Function get_TransStatus() As Boolean

Return Me.thisTransactionOn

End Function

Public Function set_TransObj(ByVal value As SqlTransaction) As SqlTransaction

Me.myTrans = value

End Function

Public Function get_TransObj(ByVal value As SqlTransaction) As SqlTransaction

Return Me.myTrans

End Function

End Class

End Namespace

二、EntityClass完成对数据库表的访问操作,根据传进来的表名,包含一个基础文件,BaseEntity.vb,代码如下:

Imports System.Data

Namespace EntityClass

Public Class BaseEntity

Public strSql As String

Public database As Data.DataFactory

Public dt As DataTable

Const ARRAYLENGTH = 100

Dim columnarray(ARRAYLENGTH) As String

Dim columnarraylen As Integer = 0

Private TABLE_NAME As String

Private mydataset As New DataSet

''构造函数

'Public Sub New()

' Me.database = New Data.DataFactory

' Me.dt = New DataTable

'End Sub

Public Sub New(ByVal tablename As String)

Me.database = New Data.DataFactory

Me.dt = New DataTable

TABLE_NAME = tablename

SetDBColoum()

End Sub

'得到对应数据库中的表的信息

Public Sub LoadDynamicDataset(ByRef dataset As DataSet)

strSql = "select * from " + TABLE_NAME + " where ID_I=0"

database.SelectSqlSrvRows(dataset, strSql)

End Sub

'通过读取数据库中的列名,对array1赋值

Private Sub SetDBColoum()

LoadDynamicDataset(mydataset)

Dim m_i As Integer = 0

columnarraylen = Me.mydataset.Tables.Item(0).Columns.Count

ReDim columnarray(columnarraylen)

For m_i = 0 To columnarraylen - 1

columnarray(m_i) = Me.mydataset.Tables.Item(0).Columns(m_i).ColumnName.ToString

Next

End Sub

'利用已有的hashtable对新的hashtable赋值

Public Function setEntity(ByRef newhashtable As Hashtable, ByVal oldhashtable As Hashtable) As Integer

For Each de As DictionaryEntry In oldhashtable

newhashtable.Add(de.Key, de.Value)

Next

End Function

''根据sql语句查询

'Public Function GetObjByQry(ByVal str As String) As ArrayList

' Dim myarralist As New ArrayList

' strSql = "select * from " + TABLE_NAME + str

' Dim dt As DataTable = database.DataTableResult(strSql)

' If (dt.Rows.Count > 0) Then

' For m_ai As Integer = 0 To dt.Rows.Count() - 1

' Dim myhashtable As New Hashtable

' For m_hi As Integer = 0 To columnarraylen - 1

' myhashtable.Add(columnarray(m_hi), dt.Rows(m_ai)(columnarray(m_hi)))

' Next

' myarralist.Add(myhashtable)

' 'myhashtable.Clear()

' Next

' Return myarralist

' Else

' Return Nothing

' End If

'End Function

'根据sql语句查询

Public Function GetObjByQry(ByVal str As String, ByRef myarralist As ArrayList)

strSql = "select * from " + TABLE_NAME + str

Dim dt As DataTable = database.DataTableResult(strSql)

If (dt.Rows.Count > 0) Then

For m_ai As Integer = 0 To dt.Rows.Count() - 1

Dim myhashtable As New Hashtable

For m_hi As Integer = 0 To columnarraylen - 1

myhashtable.Add(columnarray(m_hi), dt.Rows(m_ai)(columnarray(m_hi)))

Next

myarralist.Add(myhashtable)

Next

Else

End If

End Function

'新建

Public Shadows Function Creat(ByVal myhashtable As Hashtable) As Integer

If myhashtable.ContainsKey("Id_I") Then

myhashtable.Remove("Id_I")

End If

strSql = "insert into " + TABLE_NAME + " ("

For Each de As DictionaryEntry In myhashtable

strSql = strSql + de.Key + ","

Next

strSql = strSql.Substring(0, strSql.Length - 1)

strSql = strSql + ") values ('"

For Each de As DictionaryEntry In myhashtable

strSql = strSql + de.Value + "','"

Next

strSql = strSql.Substring(0, strSql.Length - 2)

strSql = strSql + ")"

Return database.ExecuteNonQuery(strSql)

End Function

''更新

Public Shadows Function Updata(ByVal myhashtable As Hashtable) As Integer

Dim ID_I As String = myhashtable.Item("ID_I")

'Dim ID_I As String = myhashtable.Item("Id_I")

If myhashtable.ContainsKey("Id_I") Then

myhashtable.Remove("Id_I")

End If

strSql = "update " + TABLE_NAME + " set "

For Each de As DictionaryEntry In myhashtable

strSql = strSql + de.Key + " ='" + de.Value + "',"

Next

strSql = strSql.Substring(0, strSql.Length - 1)

strSql = strSql + " where ID_I=" + ID_I

Return database.ExecuteNonQuery(strSql)

End Function

'删除

Public Shadows Function Delete(ByVal myhashtable As Hashtable) As Integer

Dim ID_I As String = myhashtable.Item("ID_I")

'Dim ID_I As String = myhashtable.Item("Id_I")

strSql = "delete from " + TABLE_NAME + " where ID_I='" + ID_I + "'"

Return database.ExecuteNonQuery(strSql)

End Function

'得到数据库中的列名,返回值为一数组

Public Function GetColumnArray() As String()

Return columnarray

End Function

'得到数据库中的列名,返回值为一数组

Public Function GetColumnHashTable() As Hashtable

Dim myhashtable As Hashtable

End Function

'Public Function GetDataOnTable() As DataTable

' Me.dt = Me.database.DataTableResult(Me.strSql)

' Return dt

'End Function

'Public Function GetOneObj() As Object

' Return Me.database.ReadOneLog(Me.strSql)

'End Function

'Public Function ExecuteSql() As Integer

' Return Me.database.ExecuteNonQuery(Me.strSql)

'End Function

End Class

End Namespace

三、Business层完成业务逻辑,主要实现业务逻辑以及为上层提供接口,包含一个最基本的文件BaseControl.vb,可以根据用户的需求添加自己的Control,要继承BaseControl,其代码如下:

Namespace Business

Public Class BaseControl

Private TABLE_NAME As String

Dim entity As EntityClass.BaseEntity

Public Sub New(ByVal tablename As String)

MyBase.New()

TABLE_NAME = tablename

entity = New EntityClass.BaseEntity(TABLE_NAME)

End Sub

'Dim

''根据查询语句得到一个list,里面的每一项都是一个hashtable

'Public Function GetObjByQry(ByVal str As String) As ArrayList

' Try

' Dim myarraylist As ArrayList = entity.GetObjByQry(str)

' If Not myarraylist Is Nothing Then

' Return myarraylist

' Else

' Return Nothing

' End If

' Catch ex As Exception

' MsgBox(ex.ToString)

' End Try

'End Function

'根据查询语句得到一个list,里面的每一项都是一个hashtable

Public Function GetObjByQry(ByVal str As String, ByRef myarraylist As ArrayList)

Try

entity.GetObjByQry(str, myarraylist)

Catch ex As Exception

MsgBox(ex.ToString)

End Try

End Function

'增加

Public Function AddObj(ByVal myhashtable As Hashtable)

Try

entity.Creat(myhashtable)

Catch ex As Exception

End Try

End Function

'更新

Public Function UpdateObj(ByVal myhashtable As Hashtable)

Try

entity.Updata(myhashtable)

Catch ex As Exception

End Try

End Function

'删除

Public Function DelObj(ByVal myhashtable As Hashtable)

Try

entity.Delete(myhashtable)

Catch ex As Exception

End Try

End Function

End Class

End Namespace

对于用户自己实现的Control文件,例如LogInControl,其基本的代码如下:

Namespace Business.LogIn

Public Class LogInControl

Inherits Business.BaseControl

Public Sub New(ByVal tablename As String)

MyBase.New(tablename)

End Sub

End Class

End Namespace

四、WinForm层

这层主要实现用户的界面方面,这里举一个例子,LogIn.vb

Private Sub B_LOGIN_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles B_LOGIN.Click

Dim userlist As New ArrayList

' userlist = loginctrl.GetObjByQry(" where USER_NAME_S='" + Me.T_NAME.Text + "' and PASSWORD_S='" + Me.T_PASSWORD.Text + "'")

loginctrl.GetObjByQry(" where USER_NAME_S='" + Me.T_NAME.Text + "' and PASSWORD_S='" + Me.T_PASSWORD.Text + "'", userlist)

If Not userlist Is Nothing And userlist.Count > 0 Then

'写系统运行日志

Dim loghashtable As New Hashtable

loghashtable.Add("IO_STATUS_S", "1")

loghashtable.Add("LOGIN_ID_S", Me.T_NAME.Text)

loghashtable.Add("CREATE_D", dt.Now)

sys_run_log_ctrl.AddObj(loghashtable)

'进入主界面

myForm.LogInUser = Me.T_NAME.Text

myForm.LogForm = Me.ActiveForm

Dim mainform As New WinForm.Main.MainWindow

myForm.MainForm = mainform

Me.Hide()

mainform.Show()

Else

Dim loghashtable As New Hashtable

loghashtable.Add("IO_STATUS_S", "0")

loghashtable.Add("LOGIN_ID_S", Me.T_NAME.Text)

loghashtable.Add("CREATE_D", dt.Now)

sys_run_log_ctrl.AddObj(loghashtable)

MsgBox("wrong user!")

End If

End Sub

总结:采用了这种架构之后,可以实现只要在声明Control时,将数据库中对应表的表名传递进去就可以了,这和以前文章中所述的架构相比,不用对每个表都要生成Entity和Parameter和Limits,而且现在的Control由于继承了基类,所以也相对简单了。

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有