2

I am working in LINQ to SQL, ASP.NET MVC, and C#. I have a repository called genesisRepository to connect to the database.

I have a table represented in an object called Stream. It is defined like this:

[Table]
public class Stream
{
    [HiddenInput(DisplayValue = false)]
    [Column(IsPrimaryKey = true, IsDbGenerated = true, AutoSync = AutoSync.OnInsert)]
    public long StreamID { get; set; }

    [Required(ErrorMessage = "Please enter a stream name")]
    [Column]
    public string StreamName { get; set; }

   /* Other columns removed for brevity */ 

    [Required(ErrorMessage = "Please enter a stream URL")]
    [Column]
    public string StreamUrl { get; set; }

    private EntitySet<StreamEntry> _StreamEntry;
    [System.Data.Linq.Mapping.Association(Storage = "_StreamEntry", OtherKey = "StreamID")]
    public EntitySet<StreamEntry> StreamEntry
    {
        get { return this._StreamEntry; }
        set { this._StreamEntry.Assign(value); }
    }

    private EntitySet<Stream2FieldTypes> _Stream2FieldTypes;
    [System.Data.Linq.Mapping.Association(Storage = "_Stream2FieldTypes", OtherKey = "StreamID")]
    public EntitySet<Stream2FieldTypes> Stream2FieldTypes
    {
        get { return this._Stream2FieldTypes; }
        set { this._Stream2FieldTypes.Assign(value); }
    }

}

I have a test action in my controller for creating new records inside my Stream table.

    public ActionResult StreamTest()
    {
        // create new stream
        var stream = new Genesis.Domain.Entities.Stream();

        stream.StreamUrl = "url";
        stream.StreamName = "name";
        stream.StreamBody = null;
        stream.StreamTitle = null;
        stream.StreamKeywords = null;
        stream.StreamDescription = null;

        genesisRepository.CreateStream(stream); 

        return View("Index");
    }

The function genesisRepository() looks like this:

    public long CreateStream(Stream stream)
    {            
        streamTable.InsertOnSubmit(stream);
        streamTable.Context.SubmitChanges();
        return stream.StreamID;
    }

I get a null reference error when I execute the ActionResult StreamTest(). genesisRepository is not null. streamTable is not null, and the newly create object stream is also obviously not null. The only thing I can think of that would be null are the EntitySet<T> properties which define the foreign relationships.

So, I modified the ActionResult code to be this:

    public ActionResult StreamTest()
    {
        // create new stream
        var stream = new Genesis.Domain.Entities.Stream();

        stream.Stream2FieldTypes = new EntitySet<Stream2FieldTypes>(); // new
        stream.StreamEntry = new EntitySet<StreamEntry>(); // new
        stream.StreamUrl = "url";
        stream.StreamName = "name";
        stream.StreamBody = null;
        stream.StreamTitle = null;
        stream.StreamKeywords = null;
        stream.StreamDescription = null;

        genesisRepository.CreateStream(stream); // CreateStream() returns ID as long

        return View("Index");
    }

But when I tried that, I got this error:

Exception Details: System.NullReferenceException: Object reference not set to an instance of an object.
Source Error: 
Line 58:         {
Line 59:             get { return this._Stream2FieldTypes; }
Line 60:             set { this._Stream2FieldTypes.Assign(value); } <-- the offending line
Line 61:         }
Line 62: 
Source File: C:\path\to\Stream.cs    Line: 60 

I can create a new record using streamTable.Context.ExecuteCommand("INSERT INTO genesis.dbo.Stream (StreamName, StreamUrl) VALUES ('Name', 'url');");.

I don't understand how to move forward from here. How can I simply create a new record in Stream?

quakkels
  • 11,676
  • 24
  • 92
  • 149
  • 1
    @quakkels, you should *strongly* consider not hand-coding the entity classes yourself. LinqToSql is designed very poorly in this department (the exceptions are *terrible* when you have your entity classes set up incorrectly) and you're looking at a world of hurt in your future in the long-run. – Kirk Woll Oct 06 '10 at 20:03
  • @Kirk Woll - Yes... it seems that way. The reason I used this approach is because I have been reading Steven Sanderson's book Pro ASP.NET MVC 2 Framework and all of his examples are hand coded. I don't have any knowledge of doing it any other way. – quakkels Oct 06 '10 at 20:10
  • @quakkels, sure, but sqlmetal.exe is pretty easy to use, though you will have to jump through some hoops to keep using data annotation validations on your linq-to-sql classes. – Kirk Woll Oct 06 '10 at 20:16
  • possible duplicate of [Why does LINQ to SQL think think that my new object is null when I try to add it to the database?](http://stackoverflow.com/questions/3874492/why-does-linq-to-sql-think-think-that-my-new-object-is-null-when-i-try-to-add-it) – p.campbell Oct 06 '10 at 20:21
  • @Kirk Woll - sqlmetal.exe? I kinda feel like if I had just used ado.net then all this rediculousness could be avoided. Though I'm pretty deep in a project to go back now. What is SqlMetal.exe? – quakkels Oct 06 '10 at 20:21
  • 1
    @p.campbell - I asked that question also.. and yes it is the same project. But this question is providing different information with the intent to get a solution. – quakkels Oct 06 '10 at 20:23
  • @quakkel, sqlmetal.exe is the command line tool with which you can point to a database and have it generate your entity classes for you. Honestly, all the "riduclousness" you've encountered is due to your not using this tool. (and I *do* sympathize with your pains) – Kirk Woll Oct 06 '10 at 21:06
  • Thanks for the tip. I'll check it out! – quakkels Oct 06 '10 at 21:34

1 Answers1

7

Try the following. Replace this in your class declaration:

public class Stream
{   
    private EntitySet<StreamEntry> _StreamEntry;
    private EntitySet<Stream2FieldTypes> _Stream2FieldTypes;
}

with this:

public class Stream
{   
    private EntitySet<StreamEntry> _StreamEntry = new EntitySet<StreamEntry>();
    private EntitySet<Stream2FieldTypes> _Stream2FieldTypes = new EntitySet<Stream2FieldTypes>();
}
Francisco
  • 4,104
  • 3
  • 24
  • 27