NullReferenceException when calling InsertOnSubmit in Linq to Sql

I am trying to insert a new object into my database using LINQ to SQL, but I get a NullReferenceException when I call InsertOnSubmit () in the code snippet below. I pass in a derived class named FileUploadAudit and all the object properties are set.

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;
        }
    }           
}

      

Here's the stack trace:

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

      

I added the following to the Audit class:

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);
    }
}

      

And the resulting FileUploadAudit looks like this:

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; }
}

      

Any ideas what the problem is? The closest question I could find for mine is here , but my partial audit class calls the parameterless constructor in the generated code and I still get the problem.

UPDATE:

This issue only occurs when I pass the derived class FileUploadAudit, the audit class works fine. The Audit class is instantiated as a linq to sql class and there are no properties mapped to database fields in the derived class.

+2


source to share


3 answers


After doing a little research, I have come to the conclusion that there is no easy way to solve this problem directly for passing in an inherited object. Perhaps the card inheritance hierarchy , but that has nothing to do with what you are pretending to be. You just want to submit base

class

and don't care if it's actually a derivative class

.

If you don't want to use partial class

to add additional properties or behavior to your table class as mentioned in the section you mentioned, I would follow the simple Clone method as a workaround:



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

      

+3


source


Try to create a base abstract class that only has property IDs and typeDiscriminator; after that create a concrete class that inherits from the base and eventually other classes that inherit from the latter. Do not include properties in derived classes that are already present in the base.

Example. Assuming a base abstract class named BasePeoples, which has a property ID and type Discriminator, we have a class of type Person that inherits from base and two other classes of type Fisherman and Driver that inherits the form Person.



So you should be able to do something like this

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


source


If you just want to pre-configure things, an alternative to inheritance could be:

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

      

0


source







All Articles