如果我没有编写用于实例化该对象的类,我可以序列化一个对象吗?

时间:2010-04-15 14:17:32

标签: asp.net-mvc linq-to-sql serialization

我有一个简单的课程

[Serializable]
public class MyClass
{
  public String FirstName { get; set: }
  public String LastName { get; set: }

  //Bellow is what I would like to do
  //But, it's not working
  //I get an exception
  ContactDataContext db = new ContactDataContext();

  public void Save()
  {
   Contact contact = new Contact();
   contact.FirstName = FirstName;
   contact.LastName = LastName;

   db.Contacts.InsertOnSubmit(contact);
   db.SubmitChanges();
  }
}

我想在类中附加一个Save方法,以便我可以在每个对象上调用它。当我介绍上面包含 ContactDataContext 的语句时,我收到以下错误“在汇编中... PublicKeyToken = null'未标记为可序列化

很明显,DataContext类是由framework()生成的。我查了一下,没看到那个班级被标记为序列化

我能做些什么来克服这个问题?当我不是班级的作者时,规则是什么? 请继续将DataContext类标记为可序列化,并假装一切正常?

感谢您的帮助

4 个答案:

答案 0 :(得分:2)

可能值得退后一步,看看你想要达到的目标是否真的有效。

通常,可序列化类用于两层之间的数据传输。它更可能是一个只保存数据的简单类。

它能够持久保存到数据库似乎有点不合适。管道的两端实际上都不可能访问数据库,并且它们似乎都不太可能具有持久化数据的能力。

我想知道是否值得将保存存储到存储库中。所以有一个存储库类,它将接受数据传输对象,构造数据库对象并保存它。

这将简化您的代码并完全避免您遇到的问题。它还将大大提高可测试性。

答案 1 :(得分:1)

问题是db字段被序列化了,显然它不需要序列化(一旦创建了对象就会实例化)。

因此,您应该使用NonSerialized属性装饰它:

[NonSerialized] 
ContactDataContext db = new ContactDataContext();

<强> [更新]

要确保在对象初始化后可以访问db字段,您应该使用lazy loading property并使用此属性而不是字段:

[NonSerialized] 
ContactDataContext db = null;

[NonSerialized] 
private ContactDataContext {
    get {
        if (db == null) {
            db = new ContactDataContext();
        }
        return db;
    }
    set {
        db = value;
    }
}

public void Save()
{
    Contact contact = new Contact();
    contact.FirstName = FirstName;
    contact.LastName = LastName;

    Db.Contacts.InsertOnSubmit(contact);
    Db.SubmitChanges();
}

<强> [UPDATE2]

您可以序列化大多数对象,只要它具有公共无参数构造函数(或根本没有构造函数),并且没有无法序列化但需要序列化的属性/字段。如果类本身未标记为[Serializable],那么您可以使用分部类自己完成此操作。如果该类具有无法序列化的属性/字段,那么您可以通过继承该类并覆盖这些属性/字段来将它们装饰为[NonSerialized]来实现此目的。

答案 2 :(得分:1)

您可以创建一个知道如何序列化狡猾类的代理 - 请参阅here以获取示例

答案 3 :(得分:0)

我认为你确实需要修饰基类,但是,DataContext自动生成的类被标记为partial。你尝试过这样的事情吗?

[Serializable]
public partial class ContactDataContext
{
}

不确定它是否会起作用,但值得一试。