The code representation of this starts with the Order object (you'll need to write this):
[PersistorAttTable(
TableName = "Order",
EnableConcurrencyChecking = true,
EnableInitialCreationLog = false,
EnableSoftDeleting = true)]
[Serializable]
public class Order : BagBase
{
private Guid _OrderID;
// flag this prop as the primary key
[PersistorAttPK()]
public Guid OrderID
{
get { return _OrderID; }
set { _OrderID = value; }
}
private DateTime _DatePlaced;
public DateTime DatePlaced
{
get { return _DatePlaced; }
set { _DatePlaced = value; }
}
private Guid _CustomerID;
public Guid CustomerID
{
get { return _CustomerID; }
set { _CustomerID = value; }
}
private Guid _SalesPersonID;
public Guid SalesPersonID
{
get { return _SalesPersonID; }
set { _SalesPersonID = value; }
}
private OrderLine[] _Lines;
// create one-to-many association with the OrderLine object
[PersistorAttSubObject("this.OrderID = that.OrderID")]
public OrderLine[] Lines
{
get { return _Lines; }
set { _Lines = value; }
}
public override bool BaseValidateBag()
{
return true;
}
}
Note the Lines property which has a type of an OrderLine array. This infers that the relationship is a one ( the Order object ) to many ( the OrderLine objects ).
This is the code for the OrderLine object.
[PersistorAttTable(
TableName = "OrderLine",
EnableConcurrencyChecking = true,
EnableInitialCreationLog = false,
EnableSoftDeleting = true)]
[Serializable]
public class OrderLine : BagBase
{
private Guid _OrderLineID;
[PersistorAttPK()]
public Guid OrderLineID
{
get { return _OrderLineID; }
set { _OrderLineID = value; }
}
private Guid _OrderID;
public Guid OrderID
{
get { return _OrderID; }
set { _OrderID = value; }
}
private Guid _ProductID;
public Guid ProductID
{
get { return _ProductID; }
set { _ProductID = value; }
}
private decimal _Price;
public decimal Price
{
get { return _Price; }
set { _Price = value; }
}
private int _Quantity;
public int Quantity
{
get { return _Quantity; }
set { _Quantity = value; }
}
private string _ProductDescription;
public string ProductDescription
{
get { return _ProductDescription; }
set { _ProductDescription = value; }
}
public override bool BaseValidateBag()
{
return true;
}
}
This is the type of functionality that most ORM frameworks provide, but BKS-ORM provides several more:
1. Concurrency checking - to prevent data collisions. Essential for large systems.
2. Soft deleting - marks a row as deleted and prevents this row from being returned again with normal Fetches.
3. Initial creation Logs - logs the user ( a string value ) that first created this entity and the date/time
4. Adding Custom Properties - the bag objects can be used to hold any other business logic you wish. See below:
[PersistorAttIgnore()] public decimal TotalOrderPrice { get { decimal total = 0; if (Lines != null) { for (int i = 0; i < Lines.Length; i++) { total += Lines[i].Price * Lines[i].Quantity; } } return total; } }
In this example, we have added a new property ( or method, etc...) to the Order object that will calculate the total price per order. We have flagged this property with the PersistorAttIgnore attribute. The BKS-ORM framework will ignore this.
An example usage follows:
Bags.IBagPersistor oBag = Remoting.CreateObject(); Bags.Order oOrder = oBag.FetchSingleBagBaseForPK (gOrderID); decimal orderTotal = oOrder.TotalOrderPrice; string firstProduct = oOrder.Lines[0].ProductDescription;
The Remoting.CreateObject call wraps some remoting specific functions. If remoting is not needed a new operator could be used.
Creating software to solve problems. Cost Effective solutions for beautiful software. Simon Stewart, custom software solutions, software development, mvp, microsoft technologies, south africa, johannesburg, port elizabeth, lecture.