With SubSonic is there a way to express relationships without foreign keys?
Our database does not have foreign keys, but we wish to be able to use SubSonic. Are there any ways except for foreign keys to express relationships between tables?
Also see this related question开发者_如何学C
There are three possible solutions that come to my mind:
a) The hard way: Do everthing yourself
Every class that is generated by SubSonic is a partial class. You can create a new file and add the properties methods for ForeignKey relation yourself:
partial class Order
{
private OrderDetailCollection orderDetails;
public OrderDetailCollection OrderDetails
{
get
{
if (orderDetailCollection == null)
orderDetailCollection = new OrderDetailCollection()
.Where(OrderDetailCollection.Columns.OrderId, this.Id).Load();
return orderDetailCollection;
}
set
{
if (value != null)
{
foreach(OrderDetail orderDetail in value)
orderDetail.OrderId = this.Id;
}
orderDetailCollection = value;
}
}
}
public Class OrderDetail
{
private Order order;
public Order Order
{
get { return order ?? DB.Select().From<Order>()
.Where(Id).IsEqualTo(this.OrderId)
.ExecuteSingle<Order>(); }
set
{
this.OrderId = value == null ? 0 : value.Id;
this.Order = value;
}
}
}
That was written from memory and not tested. You could look at the generated code or the templates how it should be (SubSonic adds some eventhandlers for items added and removed to handle the ParentId updates and maintaining a DeleteList for usage in a BindingContext right)
b) The easy way: Set up a database for the code generation that uses foreign keys (I would recommend this solution) and let SubSonic generate the foreign key parts for you.
Don't touch your production db.
At runtime SubSonic (at least 2.x) does not rely on any real foreign keys to exist. The information schema is only queried during the DAL generation.
c) The object oriented way: Write your own SubSonic DataProvider that inherits from the one you use at the moment and override the GetTableSchema() method
public override TableSchema.Table GetTableSchema(string tableName, TableType tableType)
{
TableSchema.Table tbl = base.GetTableSchema(tableName, tableType)
if (tableName == "Orders")
{
tbl.ForeignKeys = new TableSchema.ForeignKeyTableCollection();
tbl.Columns.GetColumn("Id").ForeignKeyTableName = "OrderDetails";
TableSchema.ForeignKeyTable fkTable = new TableSchema.ForeignKeyTable(this);
fkTable.ColumnName = "OrderId";
fkTable.TableName = "OrderDetails";
tbl.ForeignKeys.Add(fkTable);
}
else if (tableName == "SomethingElse)
{
....
}
}
In this method all the information schema data is pulled from the Database and used for setting up an in memory representation of your db. Here is the MySqlInnoDbDataProvider's source: http://github.com/subsonic/SubSonic-2.0/blob/master/SubSonic/DataProviders/MySqlInnoDBDataProvider.cs
(The MySql Data Providers are a great example because the default "MySqlDataProvider" doesn't generate FK-Relations, even if used with an InnoDb DB and the "MySqlInnoDbDataProvider" inherits from it and overrides the needed parts.
In your app.config/web.config you can define the DataProvider for generation.
These suggestions are for SubSonic2 but are probably applicable for SubSonic3.
精彩评论