LINQ-to-SQL maintenance

H

Harlan Messinger

What approaches are there for maintaining a LINQ-to-SQL entity model
after its initial generation from a database, if I want to add methods
to the classes or otherwise customize them? I assume that if I rerun
SQLMetal that any customizations will be lost.

Should I use extension methods? Is there a way to use classes that I
derive from the generated classes, with the custom methods added to them?
 
M

Michael C

Harlan Messinger said:
What approaches are there for maintaining a LINQ-to-SQL entity model after
its initial generation from a database, if I want to add methods to the
classes or otherwise customize them? I assume that if I rerun SQLMetal
that any customizations will be lost.

Should I use extension methods? Is there a way to use classes that I
derive from the generated classes, with the custom methods added to them?

I believe partial classes are designed for this. I haven't used linq to sql
much as I think it's a bit rubbishy but I seem to remember it had partial
classes created for you.

Michael
 
A

Andy O'Neill

Harlan Messinger said:
What approaches are there for maintaining a LINQ-to-SQL entity model after
its initial generation from a database, if I want to add methods to the
classes or otherwise customize them? I assume that if I rerun SQLMetal
that any customizations will be lost.

Should I use extension methods? Is there a way to use classes that I
derive from the generated classes, with the custom methods added to them?

Yes they're partial classes.
I recommend extension methods.

One of the annoying aspects of these things is what happens if you change
your database once they're generated.
There's no easy way to tell the IDE to just fix up this table here and add a
field.
You delete the table and drag the thing again to recreate.
So whatever you do, you want your code you write to be nicely separated from
the generated stuff that you can expect to lose.
 
H

Harlan Messinger

Andy said:
Yes they're partial classes.
I recommend extension methods.

One of the annoying aspects of these things is what happens if you
change your database once they're generated.
There's no easy way to tell the IDE to just fix up this table here and
add a field.
You delete the table and drag the thing again to recreate.
So whatever you do, you want your code you write to be nicely separated
from the generated stuff that you can expect to lose.

Ah: if they are delivered as partial classes (makes sense, I hadn't
tried this yet so I didn't realize this--so, it's like customizing
WebForms), then why do you prefer extension methods?

When I use the form designer to change a form, it leaves my .aspx.cs
partial class file untouched, so I don't have to take any special
measures to protect the custom code in the .aspx.cs files. When you say
"nicely separated", do you mean that the same isn't true for the
database-related partial classes? I need to take special measures to
protect them? What do you do to "separate" them?
 
A

Andy O'Neill

Harlan Messinger said:
measures to protect the custom code in the .aspx.cs files. When you say
"nicely separated", do you mean that the same isn't true for the
database-related partial classes? I need to take special measures to
protect them? What do you do to "separate" them?

Someone comes along and changes the table in the database.
Mismatch.
There is no "update my datacontext with the current database structure"
button.
You fix the mismatch by deleting, drag and drop again.
That's why you don't change the generated code.
 
H

Harlan Messinger

Andy said:
Someone comes along and changes the table in the database.
Mismatch.
There is no "update my datacontext with the current database structure"
button.
You fix the mismatch by deleting, drag and drop again.
That's why you don't change the generated code.

I understood why you don't change the *generated* code. I was following
up on your advice about using partial classes. When you mentioned them,
I understood that my custom code would be in separate files, as that's
the whole idea of partial classes: to be able to keep custom code
separate from generated code. But from the way you emphasized the need
to keep my code "nicely separated", I thought you might mean that there
was some protection I needed beyond that--I just didn't know what that
might be. I may have misunderstood.
 
M

Mr. Arnold

Harlan Messinger said:
I understood why you don't change the *generated* code. I was following
up on your advice about using partial classes. When you mentioned them,
I understood that my custom code would be in separate files, as that's
the whole idea of partial classes: to be able to keep custom code
separate from generated code. But from the way you emphasized the need
to keep my code "nicely separated", I thought you might mean that there
was some protection I needed beyond that--I just didn't know what that
might be. I may have misunderstood.
.

Just watching the correspondence between you two, I see now why I was told
to not directly tie code to a ADO.NET Entity Framework object in the EF
fourm.

This would seem to apply to to Linq-2-SQL Entites as well. As new versions
comeout and code is directly tied to an Entity, things may well break due to
this direct tie of code to an Entity moving to new versions of the software.

This is why one uses Data Transfer Objects DTO's, an abstraction layer above
the Model, and disconnect from Model objects.
 
H

Harlan Messinger

Mr. Arnold said:
Just watching the correspondence between you two, I see now why I was told
to not directly tie code to a ADO.NET Entity Framework object in the EF
fourm.

This would seem to apply to to Linq-2-SQL Entites as well. As new versions
comeout and code is directly tied to an Entity, things may well break due to
this direct tie of code to an Entity moving to new versions of the software.

This is why one uses Data Transfer Objects DTO's, an abstraction layer above
the Model, and disconnect from Model objects.
Data Transfer Object??? This is the first I am hearing of those. So now
I am *two* generations of data access technology behind in my knowledge.

Frankly, I'm sick and tired of having to learn a new way to access data
every two years. DAO > RDO (that was a laugh, they renamed "recordsets"
to "resultsets" for no good reason, and then switched it back) > ADO >
ADO.NET > etc. I realize that LINQ is different, in that's it's both
optional and simplifying, but ... still!
 
M

Mr. Arnold

Harlan Messinger said:
Data Transfer Object??? This is the first I am hearing of those. So now
I am *two* generations of data access technology behind in my knowledge.

Frankly, I'm sick and tired of having to learn a new way to access data
every two years. DAO > RDO (that was a laugh, they renamed "recordsets"
to "resultsets" for no good reason, and then switched it back) > ADO >
ADO.NET > etc. I realize that LINQ is different, in that's it's both
optional and simplifying, but ... still!
.

DTO's have been around since the java days. .Net programmers are just
starting to understand what OOPs is about and the use of objects, which is
really what Linq-2-SQL , nHibernte, ADO.NET Entity Framework, and other ORM's
are about. It's about the usage of objects.

http://darrell.mozingo.net/2008/05/09/loading-a-dto-from-linq-to-sql.

Since Link-2-SQL and ADO.NET EF have not been around that long, they are not
mature like nHiernate that has been around for many years in Java and .NET
worlds.

So, both .NET offerings have some maturing to do.

http://weblogs.asp.net/gunnarpeipman/archive/2009/03/01/creating-dtos-using-automapper.aspx
 
A

Arne Vajhøj

What approaches are there for maintaining a LINQ-to-SQL entity model
after its initial generation from a database, if I want to add methods
to the classes or otherwise customize them? I assume that if I rerun
SQLMetal that any customizations will be lost.

Should I use extension methods? Is there a way to use classes that I
derive from the generated classes, with the custom methods added to them?

I would go for the clear distinction between generated
and handwritten code.

You can generate the classes and every time the database is
changed, then you regenerate, rebuild and rerun unit tests.
If either build or unit tests fail, then you fix the problems.
You only handwrite the code using the generated code.

Or you switch to EF 4.0 which should support EF with POCO's,
so you can handwrite all the code, but only generate the
mappings.

And no - I don't believe in partial classes in this case.

Arne
 
A

Arne Vajhøj

Just watching the correspondence between you two, I see now why I was told
to not directly tie code to a ADO.NET Entity Framework object in the EF
fourm.

This would seem to apply to to Linq-2-SQL Entites as well. As new versions
comeout and code is directly tied to an Entity, things may well break due to
this direct tie of code to an Entity moving to new versions of the software.

This is why one uses Data Transfer Objects DTO's, an abstraction layer above
the Model, and disconnect from Model objects.

Isn't that just moving the problem instead of solving the problem?

Arne
 
M

Mr. Arnold

Arne said:
Isn't that just moving the problem instead of solving the problem?

Arne

No, it's not moving the problem else where. In the case of an
application changing ORM's, the abstraction layer of the DTO from the
Model entity allows for a smoother transition to the new ORM, nHibernate
to EF or the other way too.

In addition, DTO(s) are unused in N-Tier applications quite a bit.
Sprocs and inline T-SQL returned results are using a data reader with
mapping data to DTO(s), for best possible speed of returning results.
Some applications use sprocs with a data reader and EF in the same
solution, so DTO(s) are used.

In the case of a N-Tier WCF Web service, things have to be serialized. I
don't think a Linq-2-SQL entity is a serialized datacontract, and one
has to goto serialized DTO'(s).

However, EF entities are serialized datacontratcs so that's where the
line gets blurred between using a DTO as opposed to using a model entity
that is disconnected and used as a DTO.

It's nothing to map in both directions between DTO and entity.
 
M

Mr. Arnold

Arne Vajhøj wrote:

<snipped>
<correction>

In addition, DTO(s) are used in N-Tier applications quite a bit.
 
A

Arne Vajhøj

No, it's not moving the problem else where. In the case of an
application changing ORM's, the abstraction layer of the DTO from the
Model entity allows for a smoother transition to the new ORM, nHibernate
to EF or the other way too.

"smoother" is not a very well defined term.

You will still need to change the DTO classes.

And if you don't change the ORM but change the data, then instead
of changing business logic code you now have to change both
business logic and DTO classes.
In addition, DTO(s) are used in N-Tier applications quite a bit.
Sprocs and inline T-SQL returned results are using a data reader with
mapping data to DTO(s), for best possible speed of returning results.
Some applications use sprocs with a data reader and EF in the same
solution, so DTO(s) are used.

In the case of a N-Tier WCF Web service, things have to be serialized. I
don't think a Linq-2-SQL entity is a serialized datacontract, and one
has to goto serialized DTO'(s).

Very true.

But no so relevant for this discussion.
It's nothing to map in both directions between DTO and entity.

It is still code that need to be maintained.

I would hesitate using DTO unless there are a very specific
reason to do so (like multi remote access).

They were created for a specific purpose. They are great
for that purpose. But that does not make them great
for any purpose.

Arne
 
M

Mr. Arnold

Arne said:
"smoother" is not a very well defined term.

You will still need to change the DTO classes.

Not if everything is the same and all one did was change ORMs
And if you don't change the ORM but change the data, then instead
of changing business logic code you now have to change both
business logic and DTO classes.

It's called maintenance programming an everyday fact in enterprise
solutions.
Very true.

But no so relevant for this discussion.


It is still code that need to be maintained.

So, a property is removed, added or primitive type changes. It's not
that big of a deal, which usually happens on initial development. The
DTO rarely changes. But again maintenance is maintenance and
requirements change in the life cycle.

It happens.
I would hesitate using DTO unless there are a very specific
reason to do so (like multi remote access).

Or the DTO has another fields added to the DTO that are not on the
entity, like string Name property to hold the string name that was
looked up by ID that was mapped from the model entity. Or the developer
needs more functionality that cannot be realized on using the EF entity,
which was the no no point that was pointed out to the OP.
They were created for a specific purpose. They are great
for that purpose. But that does not make them great
for any purpose.

I see Plain Old Common Object to be no more than a DTO. They can call it
anything they want, but it's just a DTO.

So myself, I don't have a problem using DTO(s). I like them. It is what
it is and just the facts.

A single purpose program that only runs once, I have no problem using
the EF model objects and all that can buy me. But with enterprise
solutions, I'll map to DTO(s).
 
H

Harlan Messinger

Arne said:
I would go for the clear distinction between generated
and handwritten code.

You can generate the classes and every time the database is
changed, then you regenerate, rebuild and rerun unit tests.
If either build or unit tests fail, then you fix the problems.
You only handwrite the code using the generated code.

Or you switch to EF 4.0 which should support EF with POCO's,
so you can handwrite all the code, but only generate the
mappings.

And no - I don't believe in partial classes in this case.

Why not? And, in comparison or in contrast, how to you feel about
extension methods for this purpose?

It seems to me that the primary benefit of being able to use a code
generator is that it eliminates the need to hand-code (and maintain) a
large collection of classes myself. From that point of view, having to
create even another whole layer of classes to isolate my application
from the generated classes would, in part, defeat the purpose.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top