I have created an base class which my entities inherit from that gives a property called IsNew which returns true if the the value of ID is 0; all of my tables use ID for the identifier.
public abstract class EntityBase
{
public virtual int ID { get; set; }
public bool IsNew
{
get
{
return ID == 0;
}
}
}
For this to work each of my entities need to use the override modifier for the ID property. Using the O/R Designer it is possible to set the inheritance modifier for each property, but this is not possible using SQLMetal and I need to use SQLMetal to set the base class.
To overcome this I have a batch file that first creates my .dbml file using SQLMetal:
SQLMetal.exe /server:localhost /database:University /dbml:University.dbml /namespace:Entities /context:UniversityDataContext /pluralize
I then run a console application to find column nodes with the name of ID, and add the Modifier attribute:
EntityProcessor.exe University.dbml
The code for EntityProcessor looks like this:
static void Main(string[] args)
{
try
{
//Ensure there is an argument for the DBML file
if (args.Count() == 0)
{
throw new ApplicationException("DBML path expected.");
}
string dbml = args[0];
//Load the DBML file
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.Load(dbml);
//Loop through the tables
foreach (XmlNode node in xmlDoc.GetElementsByTagName("Table"))
{
//Loop through the nodes for the type
foreach (XmlNode child in node.FirstChild.ChildNodes)
{
//Find the ID column node
if (child.Name.Equals("Column") && child.Attributes["Name"].Value.Equals("ID"))
{
//Create the modifier attribute to add to ID column
XmlAttribute modifierAttribute = xmlDoc.CreateAttribute("Modifier");
modifierAttribute.Value = "Override";
child.Attributes.Append(modifierAttribute);
}
}
}
//Save the updated DBML file
xmlDoc.Save(dbml);
Console.WriteLine("Processing complete");
}
catch (Exception ex)
{
Console.WriteLine("An error occured: {0}", ex.Message);
}
}
Finally I use SQLMetal again to create my entities from the updated .dbml file:
SQLMetal.exe /code:University.cs /entitybase:EntityBase /namespace:Entities University.dbml
My new entities now have an ID property with an overrides modifier that looks like this:
[Column(Storage="_ID", AutoSync=AutoSync.OnInsert, DbType="Int NOT NULL IDENTITY", IsPrimaryKey=true, IsDbGenerated=true)]
public override int ID
{
get
{
return this._ID;
}
set
{
if ((this._ID != value))
{
this.OnIDChanging(value);
this.SendPropertyChanging();
this._ID = value;
this.SendPropertyChanged("ID");
this.OnIDChanged();
}
}
}
I can now call IsNew on any of my entities to check if they have been inserted into the database.



This post as well as most of the others have been extremely helpful to me. You have really been a big help. I was wondering however if there was a way to accomplish the EntityBase class without modifying the dbml file with your console application. My boss is having a problem with this.
Thanks so much.
Hi Michael
The console application it just to easily recreate the model after making changes to the database.
If you don’t want to use SQLMetal you can set inheritance modifiers from the properties window for the DBML file.
Cheers
I think the isnew is a cool feature and being able to set the dbml file to create entities which overrided properties from a base class is way cool. I wish you would help me …. see previous post
Hi Roberto
I don’t seem to have a previous comment from you, what is the problem?
Joe
Joe, I thought you might find this method for creating the base class helpful. I have not tried it, but I have seen this idea used in more then one place. http://www.davidturvey.com/blog/index.php/tag/linq-to-sql/
Take care
In case your interested, I found another way to accomplish this without setting the inheritance modifiers via your console app (which is very cool by the way) or via the properties window. I changed the BaseEntity to an interface instead of an abstract class. This provided the same functionality with a little less work on my part. Less work means less opportunity to make a mistake.
Thanks for all the articles. They have really been a big help to me.
Glad you found them helpful Michael
Joe
Michael how were you able to turn the Entitybase to an interface when you have the IsNew method which seems to me, would have to exist outside of an interface.