[英]How do you use hashset<string> with a binary reader in c#
我正在尝试将hashset<string>
保存到数据库然后检索它,但我不知道如何为此使用二进制阅读器。
在#region Types
中
TypeList = new Dictionary<string, Type>
我有:
[typeof(HashSet<string>).FullName]=typeof(HashSet<string>)
写它我有:
[typeof(HashSet<string>)] = (v,w) =>
{
w.Write(v != null);
if (v == null) return;
HashSet<string> datas = (HashSet<string>)v;
w.Write(datas.Count);
foreach(string data in datas)
{
w.Write(data);
}
}
但我不知道如何将它从数据库读回哈希集
[typeof(HashSet<string>)] = r=>
{
int length = r.ReadInt32();
HashSet<string> data = new HashSet<string>();
for (int i = 0; i < length; i++)
data.Add(r.ReadString());
return data;
}
这失败并出现错误:
超出 stream 的末尾后无法读取。
我对二进制阅读器的了解非常低,我不确定如何从数据库中读取哈希集。 显然循环不会完全正确,因为哈希集中没有length()
,值没有索引等,优点(以及为什么我需要在代码的其他地方使用它)是它永远不能包含两个相同的价值。
r.count
不起作用(即使这是你找到哈希集的“长度”的方式,我不知道你如何迭代 r 中的值(或者即使你是这样做的)这让我墙了两天了。
澄清:我正在添加一个开源游戏,用户数据存储在数据库中,我的哈希集数组没有保存,似乎处理数据库的 class 需要定义每种类型,这是一个区域对我来说很陌生。 以前从未真正处理过数据存储。 我得到保证,一旦我添加了定义来告诉它如何处理哈希集,那么哈希集就会保存....但是我不知道如何做那部分,我正在尝试并且已经有一段时间了(并且仍然是)。 具有讽刺意味的是,这是我正在努力保持我的思想和心理健康,同时受到保护,后者肯定会受苦
完整的 class:
using System;
using System.Collections;
using System.Collections.Generic;
using System.Drawing;
using System.IO;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using Library;
namespace MirDB
{
public sealed class DBValue
{
internal static readonly Dictionary<string, Type> TypeList;
private static readonly Dictionary<Type, Func<BinaryReader, object>> TypeRead;
private static readonly Dictionary<Type, Action<object, BinaryWriter>> TypeWrite;
static DBValue()
{
#region Types
TypeList = new Dictionary<string, Type>
{
[typeof(Boolean).FullName] = typeof(Boolean),
[typeof(Byte).FullName] = typeof(Byte),
[typeof(Byte[]).FullName] = typeof(Byte[]),
[typeof(Char).FullName] = typeof(Char),
[typeof(Color).FullName] = typeof(Color),
[typeof(DateTime).FullName] = typeof(DateTime),
[typeof(Decimal).FullName] = typeof(Decimal),
[typeof(Double).FullName] = typeof(Double),
[typeof(Int16).FullName] = typeof(Int16),
[typeof(Int32).FullName] = typeof(Int32),
[typeof(Int32[]).FullName] = typeof(Int32[]),
[typeof(Int64).FullName] = typeof(Int64),
[typeof(Point).FullName] = typeof(Point),
[typeof(SByte).FullName] = typeof(SByte),
[typeof(Single).FullName] = typeof(Single),
[typeof(Size).FullName] = typeof(Size),
[typeof(String).FullName] = typeof(String),
[typeof(TimeSpan).FullName] = typeof(TimeSpan),
[typeof(UInt16).FullName] = typeof(UInt16),
[typeof(UInt32).FullName] = typeof(UInt32),
[typeof(UInt64).FullName] = typeof(UInt64),
[typeof(Point[]).FullName] = typeof(Point[]),
[typeof(Stats).FullName] = typeof(Stats),
[typeof(BitArray).FullName] = typeof(BitArray),
[typeof(HashSet<string>).FullName]=typeof(HashSet<string>)
};
#endregion
#region Reads
TypeRead = new Dictionary<Type, Func<BinaryReader, object>>
{
[typeof(Boolean)] = r => r.ReadBoolean(),
[typeof(Byte)] = r => r.ReadByte(),
[typeof(Byte[])] = r => r.ReadBytes(r.ReadInt32()),
[typeof(Char)] = r => r.ReadChar(),
[typeof(Color)] = r => Color.FromArgb(r.ReadInt32()),
[typeof(DateTime)] = r => DateTime.FromBinary(r.ReadInt64()),
[typeof(Decimal)] = r => r.ReadDecimal(),
[typeof(Double)] = r => r.ReadDouble(),
[typeof(Enum)] = r => r.ReadInt32(),
[typeof(Int16)] = r => r.ReadInt16(),
[typeof(Int32)] = r => r.ReadInt32(),
[typeof(Int32[])] = r =>
{
if (!r.ReadBoolean()) return null;
int length = r.ReadInt32();
Int32[] values = new Int32[length];
for (int i = 0; i < length; i++)
values[i] = r.ReadInt32();
return values;
},
[typeof(Int64)] = r => r.ReadInt64(),
[typeof(Point)] = r => new Point(r.ReadInt32(), r.ReadInt32()),
[typeof(SByte)] = r => r.ReadSByte(),
[typeof(Single)] = r => r.ReadSingle(),
[typeof(Size)] = r => new Size(r.ReadInt32(), r.ReadInt32()),
[typeof(String)] = r => r.ReadString(),
[typeof(TimeSpan)] = r => TimeSpan.FromTicks(r.ReadInt64()),
[typeof(UInt16)] = r => r.ReadUInt16(),
[typeof(UInt32)] = r => r.ReadUInt32(),
[typeof(UInt64)] = r => r.ReadUInt64(),
[typeof(Point[])] = r =>
{
if (!r.ReadBoolean()) return null;
int length = r.ReadInt32();
Point[] points = new Point[length];
for (int i = 0; i < length; i++)
points[i] = new Point(r.ReadInt32(), r.ReadInt32());
return points;
},
[typeof(Stats)] = r => r.ReadBoolean() ? new Stats(r) : null,
[typeof(BitArray)] = r =>
{
if (!r.ReadBoolean()) return null;
return new BitArray(r.ReadBytes(r.ReadInt32()));
},
[typeof(HashSet<string>)] = r=>
{
int length =r.ReadInt32();
string[] temp = new string[length];
for (int i = 0; i < length; i++)
{
temp[i] = r.ReadString();
}
HashSet<string> data = new HashSet<string>();
foreach(string indata in temp)
{
data.Add(indata);
}
return data;
}
};
#endregion
#region Writes
TypeWrite = new Dictionary<Type, Action<object, BinaryWriter>>
{
[typeof(Boolean)] = (v, w) => w.Write((bool) v),
[typeof(Byte)] = (v, w) => w.Write((Byte) v),
[typeof(Byte[])] = (v, w) =>
{
w.Write(((Byte[]) v).Length);
w.Write((Byte[]) v);
},
[typeof(Char)] = (v, w) => w.Write((Char) v),
[typeof(Color)] = (v, w) => w.Write(((Color) v).ToArgb()),
[typeof(DateTime)] = (v, w) => w.Write(((DateTime) v).ToBinary()),
[typeof(Decimal)] = (v, w) => w.Write((Decimal) v),
[typeof(Double)] = (v, w) => w.Write((Double) v),
[typeof(Int16)] = (v, w) => w.Write((Int16) v),
[typeof(Int32)] = (v, w) => w.Write((Int32) v),
[typeof(Int32[])] = (v, w) =>
{
w.Write(v != null);
if (v == null) return;
Int32[] values = (Int32[]) v;
w.Write(values.Length);
foreach (Int32 value in values)
w.Write(value);
},
[typeof(Int64)] = (v, w) => w.Write((Int64) v),
[typeof(Point)] = (v, w) =>
{
w.Write(((Point) v).X);
w.Write(((Point) v).Y);
},
[typeof(SByte)] = (v, w) => w.Write((SByte) v),
[typeof(Single)] = (v, w) => w.Write((Single) v),
[typeof(Size)] = (v, w) =>
{
w.Write(((Size) v).Width);
w.Write(((Size) v).Height);
},
[typeof(String)] = (v, w) => w.Write((String) v ?? string.Empty),
[typeof(TimeSpan)] = (v, w) => w.Write(((TimeSpan) v).Ticks),
[typeof(UInt16)] = (v, w) => w.Write((UInt16) v),
[typeof(UInt32)] = (v, w) => w.Write((UInt32) v),
[typeof(UInt64)] = (v, w) => w.Write((UInt64) v),
[typeof(Point[])] = (v, w) =>
{
w.Write(v != null);
if (v == null) return;
Point[] points = (Point[]) v;
w.Write(points.Length);
foreach (Point point in points)
{
w.Write(point.X);
w.Write(point.Y);
}
},
[typeof(Stats)] = (v, w) =>
{
w.Write(v != null);
if (v == null) return;
((Stats)v).Write(w);
},
[typeof(BitArray)] = (v, w) =>
{
w.Write(v != null);
if (v == null) return;
BitArray array = (BitArray) v;
byte[] bytes = new byte[(int) Math.Ceiling(array.Length/8d)];
array.CopyTo(bytes, 0);
w.Write(bytes.Length);
w.Write(bytes);
},
[typeof(HashSet<string>)] = (v,w) =>
{
w.Write(v != null);
if (v == null) return;
HashSet<string> datas = (HashSet<string>)v;
w.Write(datas.Count);
foreach(string data in datas)
{
w.Write(data);
}
}
};
#endregion
}
public string PropertyName { get; }
public Type PropertyType { get; }
public PropertyInfo Property { get; }
public DBValue(BinaryReader reader, Type type)
{
PropertyName = reader.ReadString();
PropertyType = TypeList[reader.ReadString()];
PropertyInfo property = type?.GetProperty(PropertyName);
if (property != null)
if (property.GetCustomAttribute<IgnoreProperty>() != null)
return;
Property = property;
}
public DBValue(PropertyInfo property)
{
Property = property;
PropertyName = property.Name;
if (property.PropertyType.IsEnum)
{
PropertyType = property.PropertyType.GetEnumUnderlyingType();
return;
}
if (property.PropertyType.IsSubclassOf(typeof(DBObject)))
{
PropertyType = typeof(int);
return;
}
PropertyType = property.PropertyType;
}
public void Save(BinaryWriter writer)
{
writer.Write(PropertyName);
writer.Write(PropertyType.FullName);
}
public object ReadValue(BinaryReader reader)
{
return TypeRead[PropertyType](reader);
}
public void WriteValue(object value, BinaryWriter writer)
{
TypeWrite[PropertyType](value, writer);
}
public bool IsMatch(DBValue value)
{
return string.Compare(PropertyName, value.PropertyName, StringComparison.Ordinal) == 0 && PropertyType == value.PropertyType;
}
}
}
整个操作的某些东西似乎是错误的:
你在 memory 中有一个字符串集合。
但是,不是将其存储到具有 ForeignKey 和 VARCHAR 列的表中,而是将它们转换为字节 stream 来存储字节?
数据应尽可能长时间地保存为 DB 可处理格式。 数据完整性应该尽可能长时间地留给数据库。 您将无法对图像文件、大多数 Office 文档或类似的 BLOB 进行有意义的处理或数据完整性是不可避免的,但实际上您有可处理的字符串。
鉴于信息有限,我将创建一个包含以下内容的表:
然后对Fk_WhateverThisRelatesTo
和StringValue
的组合设置一个 UNIQUE 约束。 Fk 和 StringValues 可以重复,但两者的组合都不能。
似乎我一开始并没有阅读 boolean ......这条线让我绕弯了两天......只是看不出它不见了。
[typeof(HashSet<string>)] = r=>
{
if (!r.ReadBoolean()) return null;
int length =r.ReadInt32();
string[] temp = new string[length];
for (int i = 0; i < length; i++)
{
temp[i] = r.ReadString();
}
HashSet<string> data = new HashSet<string>();
foreach(string indata in temp)
{
data.Add(indata);
}
return data;
}
需要这一行:
if (!r.ReadBoolean()) return null;
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.