Представим ситуацию: необходимо перенести на сайт, сделанный на Orchard, большой объем каких-то данных. Например, это может быть интернет-магазин, сайт-каталог и т.д.
Допустим, нам надо создать сайт — каталог автомобилей. Для примера условимся, что для каждого автомобиля нужно хранить название модели, цену, год выпуска и количество имеющихся в наличии автомобилей. Используя исходники Orchard и немалое количество статей на тему написания модулей, создадим свой ContentType.
Model — класс Car со свойствами Model, Price, Year, Quantity:
public class CarPartRecord : ContentPartRecord
{
public virtual string Model { get; set; }
public virtual decimal Price { get; set; }
public virtual int Year { get; set; }
public virtual int Quantity { get; set; }
}
public class CarPart : ContentPart<CarPartRecord>
{
public string Model
{
get { return Record.Model; }
set { Record.Model = value; }
}
public decimal Price
{
get { return Record.Price; }
set { Record.Price = value; }
}
public int Year
{
get { return Record.Year; }
set { Record.Year = value; }
}
public int Quantity
{
get { return Record.Quantity; }
set { Record.Quantity= value; }
}
View:
@T("Model: ") @Model.Model<br />
@T("Price: ") @Model.Price<br />
@T("Year: ") @Model.Year<br />
@T("Quantity: ") @Model.Quantity<br />
Хорошо, допустим, тип контента создан. Главная проблема заключается в том, что нужный нам каталог автомобилей необходимо импортировать в Orchard. Как это сделать?
Очевидно, что при объеме данных свыше 50 записей уже хотелось бы программно добавлять их в CMS. В Orchard для того, чтобы записать данные через БД, необходимо для каждого элемента добавить записи в 5 связанных таблиц:
- ИмяМодуля_CarPartRecord
- Common_CommonPartRecord
- Common_CommonPartVersionRecord
- Orchard_Framework_ContentItemRecord
- Orchard_Framework_ContentItemVersionRecord
Дальше возможно два варианта: использовать или SQL-скрипты, или LINQtoSQL. Лично у меня, когда я проверял первый вариант, не получилось обойтись без конструкции вида
insert ... select ...
что при большом количестве записей (проверял на 3000+) приводит к совершенно неприемлемому времени работы (порядка нескольких часов).
Поэтому остановимся на втором варианте: напишем простое WinForms приложение, которое и будем производить импорт данных.
При запуске импорта должно последовательно вызываться 5 функций, добавляющих записи в каждую из вышеперечисленных таблиц, например:
private CarPartRecord create(/* строка из CSV-файла, XMLNode или любой другой формат исходных данных */)
{
CarPartRecord record = new CarPartRecord();
record.Model = //
record.Price = //заполнение полей созданного ContentPart
record.Year = //соответствующими данными
record.Quantity = //
return record;
}
private Orchard_Framework_ContentItemRecord related1_create()
{
Orchard_Framework_ContentItemRecord record = new Orchard_Framework_ContentItemRecord();
record.ContentType_id = 9; // по умолчанию в "чистой" CMS есть 8 разных ContentType, поэтому наш идет девятым
return record;
}
private Orchard_Framework_ContentItemVersionRecord related2_create(CarPartRecord item)
{
Orchard_Framework_ContentItemVersionRecord record = new Orchard_Framework_ContentItemVersionRecord();
record.Number = 1;
record.Latest = true;
record.Published = true;
record.ContentItemRecord_id = item.Id;
return record;
}
private Common_CommonPartRecord related3_create(int id) // передаем ID созданного CarPartRecord
{
Common_CommonPartRecord record = new Common_CommonPartRecord();
record.CreatedUtc = DateTime.Now;
record.ModifiedUtc = DateTime.Now;
record.PublishedUtc = DateTime.Now;
record.OwnerId = 2;
record.Id = id;
return record;
}
private Common_CommonPartVersionRecord related4_create(int id) // передаем ID созданного CarPartRecord
{
Common_CommonPartVersionRecord record = new Common_CommonPartVersionRecord();
record.CreatedUtc = DateTime.Now;
record.ModifiedUtc = DateTime.Now;
record.PublishedUtc = DateTime.Now;
record.ContentItemRecord_id = id;
record.Id = id;
return record;
}
И, соответственно, в main:
CarPartRecord record = create(/* наши параметры */);
context.CarPartRecords.InsertOnSubmit(record); //создадим запись в основной таблице
context.SubmitChanges();
Orchard_Framework_ContentItemRecord tmp1 = related1_create(); //и в остальных, используя для связи ID созданной CarPartRecord.
context.Orchard_Framework_ContentItemRecords.InsertOnSubmit(tmp1);
Orchard_Framework_ContentItemVersionRecord tmp2 = related2_create(record);
context.Orchard_Framework_ContentItemVersionRecords.InsertOnSubmit(tmp2);
Common_CommonPartRecord tmp3 = related3_create(record.Id);
context.Common_CommonPartRecords.InsertOnSubmit(tmp3);
Common_CommonPartVersionRecord tmp4 = related4_create(record.Id);
context.Common_CommonPartVersionRecords.InsertOnSubmit(tmp4);
context.SubmitChanges();
В результате импорт 3000+ записей будет длиться около 100 секунд на машине средней конфигурации. Профит.
Автор: web_mushroom