С SubSonic есть ли способ выразить отношения без внешних ключей? - PullRequest
1 голос
/ 06 июля 2010

В нашей базе данных нет внешних ключей, но мы хотим иметь возможность использовать SubSonic.Есть ли способы, кроме внешних ключей, для выражения отношений между таблицами?

Также см. этот связанный вопрос

1 Ответ

3 голосов
/ 06 июля 2010

Мне на ум приходят три возможных решения:

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.

...