我们的数据库没有外键,但我们希望能够使用SubSonic。除了用于表达表之间关系的外键之外,还有其他方法吗?
答案 0 :(得分:3)
我想到了三种可能的解决方案:
a)艰难的方法:自己做事
SubSonic生成的每个类都是一个部分类。您可以创建一个新文件并自己添加ForeignKey关系的属性方法:
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;
}
}
}
这是从记忆中写的,没有经过测试。您可以查看生成的代码或模板应该如何(SubSonic为添加和删除的项添加一些事件处理程序以处理ParentId更新并维护DeleteList以便在BindingContext中使用)
b)简单方法:为使用外键的代码生成设置数据库(我建议使用此解决方案)并让SubSonic为您生成外键部件。 请勿触摸您的生产数据库 在运行时,SubSonic(至少2.x)不依赖任何真正的外键存在。仅在DAL生成期间查询信息模式。
c)面向对象的方式:编写自己的SubSonic DataProvider,它继承自你现在使用的那个并覆盖GetTableSchema()方法
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)
{
....
}
}
在此方法中,所有信息架构数据都从数据库中提取,用于设置数据库的内存表示形式。这是MySqlInnoDbDataProvider的来源:http://github.com/subsonic/SubSonic-2.0/blob/master/SubSonic/DataProviders/MySqlInnoDBDataProvider.cs
(MySql数据提供程序是一个很好的例子,因为默认的“MySqlDataProvider”不会生成FK-Relations,即使与InnoDb数据库一起使用,并且“MySqlInnoDbDataProvider”继承了它并覆盖了所需的部分。
在app.config / web.config中,您可以定义DataProvider进行生成。
这些建议适用于SubSonic2,但可能适用于SubSonic3。