Catatan
Akses ke halaman ini memerlukan otorisasi. Anda dapat mencoba masuk atau mengubah direktori.
Akses ke halaman ini memerlukan otorisasi. Anda dapat mencoba mengubah direktori.
Mungkin ada situasi ketika pengguna atau administrator alur kerja ingin memeriksa status instans alur kerja yang bertahan secara manual. SqlWorkflowInstanceStore memberikan tampilan pada tabel Instans yang memperlihatkan empat kolom berikut:
- ReadWritePrimitiveDataProperties
- WriteOnlyPrimitiveDataProperties
- ReadWriteComplexDataProperties
- WriteOnlyComplexDataProperties
Properti data primitif mengacu pada properti yang jenis .NET-nya dianggap "umum" (misalnya, Int32 dan String), sementara properti data kompleks merujuk ke semua jenis lainnya. Enumerasi yang tepat dari jenis primitif ditemukan kemudian dalam contoh kode ini.
Properti baca/tulis mengacu pada properti yang dikembalikan kembali ke Runtime Alur Kerja saat instans dimuat. Properti WriteOnly ditulis ke database dan kemudian tidak pernah dibaca lagi.
Contoh ini menyediakan kode yang memungkinkan pengguna untuk membatalkan deserialisasi properti data primitif. Mengingat array byte yang dibaca dari kolom ReadWritePrimitiveDataProperties atau WriteOnlyPrimitiveDataProperties, kode ini akan mengonversi objek besar biner (BLOB) menjadi Dictionary<TKey,TValue> jenis <XName, object> di mana setiap pasangan nilai kunci mewakili nama properti dan nilai yang sesuai.
Penting
Microsoft menyarankan agar Anda menggunakan alur autentikasi paling aman yang tersedia. Jika Anda menyambungkan ke Azure SQL, Identitas Terkelola untuk sumber daya Azure adalah metode autentikasi yang direkomendasikan.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.IO.Compression;
using System.Xml.Linq;
using System.Xml;
using System.Globalization;
using System.Data.SqlClient;
namespace PropertyReader
{
class Program
{
const string ConnectionString = @"Data Source=localhost;Initial Catalog=Persistence;Integrated Security=True;Asynchronous Processing=True";
static void Main(string[] args)
{
string queryString = "SELECT TOP 10 * FROM [System.Activities.DurableInstancing].[Instances]";
using (SqlConnection connection =
new SqlConnection(ConnectionString))
{
SqlCommand command =
new SqlCommand(queryString, connection);
connection.Open();
SqlDataReader reader = command.ExecuteReader();
byte encodingOption;
while (reader.Read())
{
if (reader["ReadWritePrimitiveDataProperties"] != DBNull.Value)
{
encodingOption = (byte)reader["EncodingOption"];
Console.WriteLine("Printing the ReadWritePrimitiveDataProperties of the instance with Id:" + reader["InstanceId"]);
foreach (KeyValuePair<XName, object> pair in (Dictionary<XName, object>)ReadDataProperties((byte[])reader["ReadWritePrimitiveDataProperties"], encodingOption))
{
Console.WriteLine("{0}, {1}" , pair.Key, pair.Value);
}
Console.WriteLine();
}
if (reader["WriteOnlyPrimitiveDataProperties"] != DBNull.Value)
{
encodingOption = (byte)reader["EncodingOption"];
Console.WriteLine("Printing the WriteOnlyPrimitiveDataProperties of the instance with Id:" + reader["InstanceId"]);
foreach (KeyValuePair<XName, object> pair in (Dictionary<XName, object>)ReadDataProperties((byte[])reader["WriteOnlyPrimitiveDataProperties"], encodingOption))
{
Console.WriteLine("{0}, {1}", pair.Key, pair.Value);
}
Console.WriteLine();
}
}
// Call Close when done reading.
reader.Close();
}
Console.ReadLine();
}
static Dictionary<XName, object> ReadDataProperties(byte[] serializedDataProperties, byte encodingOption)
{
if (serializedDataProperties != null)
{
Dictionary<XName, object> propertyBag = new Dictionary<XName, object>();
bool isCompressed = (encodingOption == 1);
using (MemoryStream memoryStream = new MemoryStream(serializedDataProperties))
{
// if the instance state is compressed using GZip algorithm
if (isCompressed)
{
// decompress the data using the GZip
using (GZipStream stream = new GZipStream(memoryStream, CompressionMode.Decompress))
{
// create an XmlReader object and pass it on to the helper method ReadPrimitiveDataProperties
using (XmlReader reader = XmlDictionaryReader.CreateBinaryReader(stream, XmlDictionaryReaderQuotas.Max))
{
// invoke the helper method
ReadPrimitiveDataProperties(reader, propertyBag);
}
}
}
else
{
// if the instance data is not compressed
// create an XmlReader object and pass it on to the helper method ReadPrimitiveDataProperties
using (XmlReader reader = XmlDictionaryReader.CreateBinaryReader(memoryStream, XmlDictionaryReaderQuotas.Max))
{
// invoke the helper method
ReadPrimitiveDataProperties(reader, propertyBag);
}
}
return propertyBag;
}
}
return null;
}
// Reads the primitive data properties from the XML stream.
// Invoked by the ReadDataProperties method.
static void ReadPrimitiveDataProperties(XmlReader reader, Dictionary<XName, object> propertyBag)
{
const string xmlElementName = "Property";
if (reader.ReadToDescendant(xmlElementName))
{
do
{
// get the name of the property
reader.MoveToFirstAttribute();
string propertyName = reader.Value;
// get the type of the property
reader.MoveToNextAttribute();
PrimitiveType type = (PrimitiveType)Int32.Parse(reader.Value, CultureInfo.InvariantCulture);
// get the value of the property
reader.MoveToNextAttribute();
object propertyValue = ConvertStringToNativeType(reader.Value, type);
// add the name and value of the property to the property bag
propertyBag.Add(propertyName, propertyValue);
}
while (reader.ReadToNextSibling(xmlElementName));
}
}
// Invoked by the ReadPrimitiveDataProperties method.
// Given a property value as parsed from an XML attribute, and the .NET Type of the Property, recreates the actual property value
// (e.g. Given a property value of "1" and a PrimitiveType of Int32, this method returns an object of type Int32 with value 1).
static object ConvertStringToNativeType(string value, PrimitiveType type)
{
switch (type)
{
case PrimitiveType.Bool:
return XmlConvert.ToBoolean(value);
case PrimitiveType.Byte:
return XmlConvert.ToByte(value);
case PrimitiveType.Char:
return XmlConvert.ToChar(value);
case PrimitiveType.DateTime:
return XmlConvert.ToDateTime(value, XmlDateTimeSerializationMode.RoundtripKind);
case PrimitiveType.DateTimeOffset:
return XmlConvert.ToDateTimeOffset(value);
case PrimitiveType.Decimal:
return XmlConvert.ToDecimal(value);
case PrimitiveType.Double:
return XmlConvert.ToDouble(value);
case PrimitiveType.Float:
return float.Parse(value, CultureInfo.InvariantCulture);
case PrimitiveType.Guid:
return XmlConvert.ToGuid(value);
case PrimitiveType.Int:
return XmlConvert.ToInt32(value);
case PrimitiveType.Long:
return XmlConvert.ToInt64(value);
case PrimitiveType.SByte:
return XmlConvert.ToSByte(value);
case PrimitiveType.Short:
return XmlConvert.ToInt16(value);
case PrimitiveType.String:
return value;
case PrimitiveType.TimeSpan:
return XmlConvert.ToTimeSpan(value);
case PrimitiveType.Type:
return Type.GetType(value);
case PrimitiveType.UInt:
return XmlConvert.ToUInt32(value);
case PrimitiveType.ULong:
return XmlConvert.ToUInt64(value);
case PrimitiveType.Uri:
return new Uri(value);
case PrimitiveType.UShort:
return XmlConvert.ToUInt16(value);
case PrimitiveType.XmlQualifiedName:
return new XmlQualifiedName(value);
case PrimitiveType.Null:
case PrimitiveType.Unavailable:
default:
return null;
}
}
// .NET Types that SQL Workflow Instance Store considers to be Primitive. Any other .NET type not listed in this enumeration is a "Complex" property.
enum PrimitiveType
{
Bool = 0,
Byte,
Char,
DateTime,
DateTimeOffset,
Decimal,
Double,
Float,
Guid,
Int,
Null,
Long,
SByte,
Short,
String,
TimeSpan,
Type,
UInt,
ULong,
Uri,
UShort,
XmlQualifiedName,
Unavailable = 99
}
}
}
Contoh ini tidak menunjukkan cara mendeserialisasi properti data kompleks karena itu adalah operasi yang tidak didukung.