GvS
GvS

Reputation: 52518

Initialize a Linq to Sql object via business logic

I would like to extend a class generated by Linq To Sql to initialize when a new object (=row) is created.

I want to add rows to a child table when a parent row is created.

I was hoping to use the Oncreated (partial) method do something like this:

partial class Product {
    partial void OnCreated() {
        // Fill default rows for FK relations
        this.Columns.Add(new ProductColumn {
            Name = "Name", ColumnType = 1
        });
        this.Columns.Add(new ProductColumn {
            Name = "Producer", ColumnType = 2
        });
    }
}

The OnCreated is called every time from the constructor. So also if the object will be loaded from the database after the call to OnCreated. And if the object is loaded from the database, do not want to execute the code.

So where can I add logic to my model to initialize an object(-graph)?

Upvotes: 2

Views: 2879

Answers (4)

Marc Gravell
Marc Gravell

Reputation: 1062600

With LINQ-to-SQL, the entities are largely unaware of the parent data-context - only lazy-loaded members like EntitySet<T> know about this detail. You can identify data-context aware entity-sets by looking at .IsDeferred (assuming it is deferred) - this will be true if a data-context is involved, and false otherwise - but there are further problems:

  • LINQ-to-SQL attaches the data-context (for deferred execution) after the constructur (and OnCreated) has executed
  • If you add items manually in OnCreated/.ctor(), it breaks when LINQ-to-SQL attempts to attach the data-context
  • LINQ-to-SQL uses the default constructor, meaning that generics/new() etc will also share this code

So unfortunately; no, I don't think you can do this in OnCreated in any sensible way. You could:

  • have a second constructor for this use, that adds the extra items
  • use a factory method, i.e. a static .Create() method that builds items correctly

(since LINQ-to-SQL won't use either of the above itself)

Upvotes: 2

Paul
Paul

Reputation: 36319

There's no built in method for it in the Linq to SQL generated classes. They call OnLoaded specifically when called from the DB, but they do not call anything when it's not. I suspect because there's no way to know for sure...

I'd recommend using the factory approach that Chris suggested.

Upvotes: 3

Chris Shaffer
Chris Shaffer

Reputation: 32575

I think you'd be better off in this instance to use a Factory to create your instances; So anywhere you current have code like:

Product p = new Product();

You would instead have:

Product p = ProductFactory.CreateProduct();

And your CreateProduct() method would look something like:

public Product CreateProduct()
{
    var p = new Product();
    p.Columns.Add(new ProductColumn {
        Name = "Name", ColumnType = 1
    });
    p.Columns.Add(new ProductColumn {
        Name = "Producer", ColumnType = 2
    });
    return p;
}

Upvotes: 1

tvanfosson
tvanfosson

Reputation: 532435

If you are using the designer -- and I presume you are because you are using partial classes -- you can add the association in the designer and the appropriate columns will get added to your object automatically. MSDN has a reference on how to create associations using the designer work surface.

Upvotes: 0

Related Questions