2009-10-15 57 views
2

我試圖插入一個新的對象到我的數據庫使用LINQ to SQL,但得到一個NullReferenceException當我調用下面的代碼片段中的InsertOnSubmit()。我傳入一個名爲FileUploadAudit的派生類,並且設置了該對象上的所有屬性。NullReferenceException當在Linq中調用InsertOnSubmit到SQL

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" 

我已經添加到審計類是這樣的:

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,但我的部分Audit類正在調用生成的代碼中的無參數構造函數,而且我仍然遇到問題。

UPDATE:

此問題只當我通過在派生類FileUploadAudit發生,審計類工作正常。 Audit類是作爲linq to sql類生成的,並且沒有將屬性映射到派生類中的數據庫字段。

+0

您可以張貼在堆棧跟蹤例外? – 2009-10-15 13:17:54

+0

添加了堆棧跟蹤,但它沒有多大幫助 – Charlie 2009-10-15 13:34:11

回答

3

經過一番小小的研究,我得出的結論是,沒有簡單的方法可以直接解決提交繼承對象的問題。有可能Map Inheritance Hierarchies但這與你假裝沒有任何關係。你只是想提交baseclass,不關心它是否實際上是派生的class

如果你不想使用partial class額外的屬性或行爲添加到您的表類,如你所提到的thread的建議,我會做一個簡單的克隆方法作爲一種解決方法:

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()); 
+0

謝謝,這幾乎是我想要得出的結論。 – Charlie 2009-10-15 15:35:21

0

嘗試創建僅具有屬性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(); 

     } 
0

如果你只是想預先配置的東西,繼承另一種可能是:

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 
相關問題