I know you can customise entities through partial classes, but what is the general approach for modifying properties on entities? What if i want to change the logic in the get/set? What about adding attributes? I don't want to edit the auto generated code - how do people get around this?
Don't autogenerate code at all. You can build your own linq to sql classes without using the designer.
Edit: My lazy way of doing this would be to autogenerate the code, copy paste it into the non generated file, and delete the designer files. Up to you though.
The Linq2SQL classes are partial classes, which means you can easily extend them by adding your own separate file and declaring another part of the partial class in there.
In that file, you can customize the class as needed - and since it's a separate file, the code generation will not overwrite it.
If you look at e.g. the "Contact" class in the AdventureWorks database, Linq2SQL will generate this in your AdventureWorks.designer.cs file:
[Table(Name="Person.Contact")]
public partial class Contact : INotifyPropertyChanging, INotifyPropertyChanged
{
Now you can add a "Contact.cs" file to your project, and extend that partial class, e.g. by introducing a new property "DisplayName":
public partial class Contact
{
public string DisplayName
{
get { return string.Format("{0} {1}", FirstName, LastName); }
}
}
At compile time, these two parts of the class are merged together.
The other part are the partial methods - methods that are available for you to implement, but if they're not implemented, calls to them are being optimized out by the compiler.
For each object class in Linq2SQL, a whole slew of partial methods (a new feature in .NET 3.0) are being created - up to you to implement those!
partial void InsertContact(Contact instance);
partial void UpdateContact(Contact instance);
partial void DeleteContact(Contact instance);
partial void OnLoaded();
partial void OnValidate(System.Data.Linq.ChangeAction action);
partial void OnCreated();
partial void OnFirstNameChanging(string value);
partial void OnFirstNameChanged();
partial void OnLastNameChanging(string value);
partial void OnLastNameChanged();
Plenty of extension points!
Marc
As Linq2Sql Entities are not sealed you could derive from a Linq2Sql class and do your changes in the derived class.
In my projects, I wouldn't do any changes to a Linq2Sql class. Instead I build my own set of POCO's which I can tailor to my needs. Then I use Linq2Sql only to fill / persist my POCO's using a repository pattern.
Rob Connery has a great webcast series on his blog called ASP.NET MVC Storefront. In one of the first webcasts he covers using Linq2Sql as a repository in conjunction with POCO's
Check this out:
It's WAY better than sqlmetal (which is what the designer uses to generate your code)
http://plinqo.com/default.aspx?AspxAutoDetectCookieSupport=1
Requires a Codesmith license though, but IMHO is very worth it.
Modifying the logic in get/set of properties in a class that isn't marked virtual isn't possible without some serious hacks (look into mocking frameworks for examples of how to get around those limitations). That is the whole point of marking something virtual, making it expendable at the cost of a virtual call and a performance hit.
The Metadatatype tag, however, will allow you to annotate an existing class with attributes that you can't modify:
Note: stolen from this related question
[MetadataType (typeof (BookingMetadata))]
public partial class Booking
{
// This is your custom partial class
}
public class BookingMetadata
{
[Required] [StringLength(15)]
public object ClientName { get; set; }
[Range(1, 20)]
public object NumberOfGuests { get; set; }
[Required] [DataType(DataType.Date)]
public object ArrivalDate { get; set; }
}