【问题标题】:NullReferenceException when calling InsertOnSubmit in Linq to Sql在 Linq to Sql 中调用 InsertOnSubmit 时出现 NullReferenceException
【发布时间】:2009-10-15 12:58:04
【问题描述】:

我正在尝试使用 LINQ to SQL 将新对象插入到我的数据库中,但是当我在下面的代码 sn-p 中调用 InsertOnSubmit() 时得到 NullReferenceException。我传入了一个名为 FileUploadAudit 的派生类,并设置了对象的所有属性。

public void Save(Audit audit)
{
    try
    {                
        using (ULNDataClassesDataContext dataContext = this.Connection.GetContext())
        {
            if (audit.AuditID > 0)
            {
                throw new RepositoryException(RepositoryExceptionCode.EntityAlreadyExists, string.Format("An audit entry with ID {0} already exists and cannot be updated.", audit.AuditID));
            }

            dataContext.Audits.InsertOnSubmit(audit);
            dataContext.SubmitChanges();
        }
    }
    catch (Exception ex)
    {
        if (ObjectFactory.GetInstance<IExceptionHandler>().HandleException(ex))
        {
            throw;
        }
    }           
}

这是堆栈跟踪:

at System.Data.Linq.Table`1.InsertOnSubmit(TEntity entity)
at XXXX.XXXX.Repository.AuditRepository.Save(Audit audit) 
C:\XXXX\AuditRepository.cs:line 25"

我已经像这样添加到 Audit 类中:

public partial class Audit
{ 
    public Audit(string message, ULNComponent component) : this()
    {
        this.Message = message;
        this.DateTimeRecorded = DateTime.Now;
        this.SetComponent(component);
        this.ServerName = Environment.MachineName;
    }           
    public bool IsError { get; set; }     
    public void SetComponent(ULNComponent component)
    {
        this.Component = Enum.GetName(typeof(ULNComponent), component);
    }
}

派生的 FileUploadAudit 看起来像这样:

public class FileUploadAudit : Audit
{ 
    public FileUploadAudit(string message, ULNComponent component, Guid fileGuid, string originalFilename, string physicalFilename, HttpPostedFileBase postedFile)
        : base(message, component)
    {
        this.FileGuid = fileGuid;
        this.OriginalFilename = originalFilename;
        this.PhysicalFileName = physicalFilename;
        this.PostedFile = postedFile;
        this.ValidationErrors = new List<string>();
    }
    public Guid FileGuid { get; set; }
    public string OriginalFilename { get; set; }
    public string PhysicalFileName { get; set; }
    public HttpPostedFileBase PostedFile { get; set; }
    public IList<string> ValidationErrors { get; set; }
}

任何想法是什么问题?我能找到的最接近的问题是here,但我的部分审计类在生成的代码中调用无参数构造函数,我仍然遇到问题。

更新:

只有当我传入派生的 FileUploadAudit 类时才会出现此问题,Audit 类工作正常。 Audit 类作为 linq to sql 类生成,并且没有属性映射到派生类中的数据库字段。

【问题讨论】:

  • 你能发布异常的堆栈跟踪吗?
  • 添加了堆栈跟踪,但没有多大帮助

标签: c# .net linq-to-sql nullreferenceexception


【解决方案1】:

经过一番研究,我得出的结论是,没有简单的方法可以解决直接提交继承对象的问题。 Map Inheritance Hierarchies 是可能的,但这与你假装的无关。您只想提交 base class 而不在乎它是否实际上是派生的 class

如果您不想使用partial class 向您的表类添加其他属性或行为,如您提到的thread 中所建议的那样,我会做一个简单的 Clone 方法作为一种解决方法:

    public partial class Audit
    {
        // ...
        public Audit Concrete()
        {
            if (this.GetType().Equals(typeof(Audit)))
                return this;
            else
            {
                Audit audit = new Audit();
                // clone properties
                return audit;
            }
        }
    }

//...
dataContext.Audits.InsertOnSubmit(audit.Concrete());

【讨论】:

  • 谢谢,这几乎是我得出的结论。
【解决方案2】:

尝试创建一个只有属性 ID 和 typeDiscriminator 的基本抽象类;之后创建从基类继承的具体类,并最终创建从最后一个继承的其他类。 不要在派生类中包含已经存在于基类中的属性。

示例:假设一个名为 BasePeoples 的基本抽象类具有属性 ID 和 typeDiscriminator,我们有一个从基类继承的 Person 类型的类以及从 Person 继承的 Fisherman 和 Driver 类型的另外两个类。

这样你就可以做这样的事情了

using (DatabaseDataContext db = new DatabaseDataContext())
        {
            Person p = new Person();
            p.FirstName = "Dario";
            p.LastName = "Iacampo";

            Fisherman f = new Fisherman();
            f.FirstName = "San";
            f.LastName = "Pei";
            f.CollectedFishes = 10;
            f.FishingLicenceNumber = "abc";

            Driver d = new Driver();
            d.FirstName = "Michael";
            d.LastName = "Shumaker";
            d.CarMake = "Ferrari";
            d.DrivingLicenceNumber = "123abc";

            db.BasePeoples.InsertOnSubmit(f);
            db.BasePeoples.InsertOnSubmit(d);
            db.SubmitChanges();

        }

【讨论】:

    【解决方案3】:

    如果您只想预先配置一些东西,继承的替代方法可能是:

    partial class MyLinqClass {
        string Text = "Default";
    
        public MyLinqClass AsOne() {
            Text = "One";
            ...
            return this;
        }
    }
    
    var x = new MyLinqClass().AsOne();
    context.InsertOnSubmit(x); // x is type MyLinqClass
    

    【讨论】:

      猜你喜欢
      • 2011-01-12
      • 2011-01-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-10-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多