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.