我有一个包含 C#/VB.NET 的 n 层业务应用程序项目,并且在获取更新方法以在层之间进行通信时遇到问题。在最接近数据库的数据层中,我有一个 GetByID() 方法,该方法根据员工在数据库中的 ID 查找员工,并将他们的头衔、名字等以及整个实体(序列化)放在字典中。
在下一层(业务用户)中,我尝试将其私有成员设置为调用数据层 GetByID() 方法的业务用户 GetByID() 方法的结果。我在这里尝试设置我的私人成员
_entity = (byte[])retDict["entity"];
这给了我错误不能隐式键入 byte[] 到 System.Type,因为_entity是一个类型。
在VB中完成的表示层通过listview选择值传递employeeID,然后该值又向下传递到用户层和数据层。
以下是 EmployeeBusinessData 层 GetByID() 代码:
public byte[] GetByID(int empid)
{
Dictionary<string, Object> retDict = new Dictionary<string, Object>();
try
{
HelpDeskDBEntities dbContext = new HelpDeskDBEntities();
dbContext.Configuration.ProxyCreationEnabled = false;
Employee EmployeeEntity = dbContext.Employees.FirstOrDefault(emp => emp.EmployeeID == empid);
if (EmployeeEntity != null)
{
retDict["title"] = EmployeeEntity.Title;
retDict["firstname"] = EmployeeEntity.FirstName;
retDict["lastname"] = EmployeeEntity.LastName;
retDict["phoneno"] = EmployeeEntity.PhoneNo;
retDict["email"] = EmployeeEntity.Email;
retDict["departmentid"] = EmployeeEntity.DepartmentID;
retDict["employeeid"] = EmployeeEntity.EmployeeID;
retDict["entity"] = Serializer(EmployeeEntity, true);
}
else
{
retDict["error"] = "Employee not found!";
}
}
catch (Exception ex)
{
ErrorRoutine(ex, "EmployeeBusinessData", "GetByID");
}
return Serializer(retDict);
}
和 EmployeeBusinessUser 层 GetById():
public byte[] GetByID(int empid)
{
Dictionary<string, Object> retDict = new Dictionary<string, object>();
try
{
EmployeeBusinessData empData = new EmployeeBusinessData();
retDict = (Dictionary<string, Object>)Deserializer(empData.GetByID(empid));
_employeeID = Convert.ToInt32(retDict["employeeid"]);
_title = Convert.ToString(retDict["title"]);
_firstName = Convert.ToString(retDict["firstname"]);
_lastName = Convert.ToString(retDict["lastname"]);
_phoneNo = Convert.ToString(retDict["phoneno"]);
_email = Convert.ToString(retDict["email"]);
_departmentID = Convert.ToInt32(retDict["departmentid"]);
_entity = (byte[])retDict["entity"];
}
catch (Exception ex)
{
ErrorRoutine(ex, "EmployeeUserData", "GetByID");
}
return Serializer(retDict);
}
这也是序列化程序方法代码,它在两个类.dll中都是相同的:
public static byte[] Serializer(Object inObject, bool bIsEntity = false)
{
byte[] ByteArrayObject;
if (bIsEntity) //If the entity uses DataContractSerializer
{
MemoryStream strm = new MemoryStream();
var serializer = new DataContractSerializer(inObject.GetType());
serializer.WriteObject(strm, inObject);
ByteArrayObject = strm.ToArray();
}
else
{
BinaryFormatter frm = new BinaryFormatter();
MemoryStream strm = new MemoryStream();
frm.Serialize(strm, inObject);
ByteArrayObject = strm.ToArray();
}
return ByteArrayObject;
}
private Type _entity;
两种不同的反序列化程序类型:
public static Object Deserializer(byte[] ByteArrayIn, Type entityType)
{
MemoryStream stream = new MemoryStream(ByteArrayIn);
DataContractSerializer ser = new DataContractSerializer(entityType);
Object returnObject = ser.ReadObject(stream);
return returnObject;
}
public static Object Deserializer(byte[] ByteArrayIn)
{
BinaryFormatter frm = new BinaryFormatter();
MemoryStream strm = new MemoryStream(ByteArrayIn);
Object returnObject = frm.Deserialize(strm);
return returnObject;
}
如何让 retDict["实体"] 转换为字节,以便将其分配给_entity?
这是你的问题:
private Type _entity;
您可能想要一个 Employee 对象,如下所示:
private Employee _entity;
或者,如果您想要一个可以容纳任何类型的对象(或实体)的变量,请使用 object
类型:
private object _entity;
.NET 中的Type
是表示类类型的类,而不是类本身。
因此,如果我有这样的类:
public class Person
{
}
我可以将其存储在 Person 变量中:
Person somePerson = new Person();
或者在对象变量中:
object someObject = new Person();
但我只能将对象的类型存储在Type
变量中:
Type someType = typeof(Person);
或者,如果你有一个对象的实例,你可以得到它的类型,如下所示:
Person somePerson = new Person();
Type typeOfSomePerson = somePerson.GetType();
但是您可能根本不想要该类型。
编辑:
我注意到您在问题中没有反序列化两次。 您首先序列化实体,然后单独序列化其字段。 我不确定你为什么要对所有内容进行两次序列化。 但至少你需要反序列化它两次。
所以改变这个:
_entity = (byte[])retDict["entity"];
对此:
_entity = (Employee)Deserialize((byte[])retDict["entity"], typeof(Employee));
这实际上是在说,"从字典中检索 Employee 的序列化字节,将字节反序列化到 Employee 实例中,并将其强制转换为 Employee,因为该方法的返回类型是 object。
但就像我说的,你似乎在每个领域做了两次。 只需序列化实体本身一次,然后再次反序列化实体。 除非你的逻辑缺少什么。