Импорт в Orchard Cms просто импортирует последнюю запись

Я пытаюсь импортировать данные в Orchard CMS. У меня есть пользовательская часть, я переопределил метод импорта в драйвере и использую модуль импорта/экспорта.

Я экспортировал некоторые данные из Orchard, чтобы убедиться, что XML-схема верна, но при импорте импортируется только последняя запись, независимо от того, какие данные в ней содержатся.

Я также зашифровал записи в xml, и единственная импортированная запись всегда является последней записью, у которой есть идентификатор, отличный от нуля. Поэтому я могу сказать, что это не проблема действительных или недействительных данных. Все записи действительны, и они будут импортированы, если у них есть идентификатор (который будет заменен следующим автоматически сгенерированным ключом) и они являются последними в наборе.

Никаких ошибок в логах.

Я использую Orchard 1.7.2.0 из репозитория git.

Я использую SQL compact в качестве механизма БД.

Любая идея, почему это терпит неудачу?

Это запись партии:

public class VehiclePartRecord : ContentPartRecord
{
    public virtual string Name { get; set; }
    public virtual byte VehicleRole { get; set; }
    public virtual string Identification { get; set; }
    public virtual string RadioCode { get; set; }
    public virtual int StartKm { get; set; }
    public virtual string Note { get; set; }
    public virtual DateTime StartDate { get; set; }
    public virtual DateTime EndDate { get; set; }
    public virtual bool Active { get; set; }
}

Это драйвер:

    protected override void Importing(VehiclePart part, ImportContentContext context)
    {
        var name = context.Attribute(part.PartDefinition.Name, "Name");
        if (name != null) {
            part.Name = name;
        }
        var vehicleRole = context.Attribute(part.PartDefinition.Name, "VehicleRole");
        if (!string.IsNullOrWhiteSpace(vehicleRole)) {
            part.VehicleRole = byte.Parse(vehicleRole);
        }
        var identification = context.Attribute(part.PartDefinition.Name, "Identification");
        if (!string.IsNullOrWhiteSpace(identification)) {
            part.Identification = identification.TrimEnd();
        }
        var radioCode = context.Attribute(part.PartDefinition.Name, "RadioCode");
        if (!string.IsNullOrWhiteSpace(radioCode)) {
            part.RadioCode = radioCode.TrimEnd();
        }
        var startKm = context.Attribute(part.PartDefinition.Name, "StartKm");
        if (!string.IsNullOrWhiteSpace(startKm)) {
            part.StartKm = int.Parse(startKm);
        }
        var note = context.Attribute(part.PartDefinition.Name, "Note");
        if (note != null) {
            part.Note = note;
        }
        var startDate = context.Attribute(part.PartDefinition.Name, "StartDate");
        if (!string.IsNullOrWhiteSpace(startDate)) {
            part.StartDate = DateTime.Parse(startDate);
        }
        var endDate = context.Attribute(part.PartDefinition.Name, "EndDate");
        if (!string.IsNullOrWhiteSpace(endDate)) {
            part.EndDate = DateTime.Parse(endDate);
        }
        var active = context.Attribute(part.PartDefinition.Name, "Active");
        if (!string.IsNullOrWhiteSpace(active)) {
            part.Active = bool.Parse(active);
        }
    }

И это экспортированный файл, который я редактировал и пытаюсь импортировать:

<!--Exported from Orchard-->
<Orchard>
    <Recipe>
        <Name>Generated by Orchard.ImportExport</Name>
        <Author>admin</Author>
        <ExportUtc>2013-11-22T11:39:39.9566929Z</ExportUtc>
    </Recipe>
    <Data>
        <Vehicle Id="4" Status="Published">
            <VehiclePart Name="Fiat Punto" VehicleRole="2" Identification="EL 999 LV" RadioCode="013" StartKm="0" Note="" StartDate="2008-04-12T00:00:00" EndDate="" Active="true" />
            <CommonPart Owner="/User.UserName=admin" CreatedUtc="2013-11-22T10:27:57.7066182Z" PublishedUtc="2013-11-22T10:27:57.7296195Z" ModifiedUtc="2013-11-22T10:27:57.7356199Z" />
        </Vehicle>
        <Vehicle Id="8" Status="Published">
            <VehiclePart Name="Fiat Punto" VehicleRole="2" Identification="EL 888 LV" RadioCode="014" StartKm="0" Note="" StartDate="2009-04-12T00:00:00" EndDate="" Active="true" />
            <CommonPart Owner="/User.UserName=admin" CreatedUtc="2013-11-22T10:27:57.7066182Z" PublishedUtc="2013-11-22T10:27:57.7296195Z" ModifiedUtc="2013-11-22T10:27:57.7356199Z" />
        </Vehicle>
        <Vehicle Id="12" Status="Published">
            <VehiclePart Name="Fiat Punto" VehicleRole="2" Identification="EL 777 LV" RadioCode="017" StartKm="0" Note="" StartDate="2010-03-02T00:00:00" EndDate="" Active="true" />
            <CommonPart Owner="/User.UserName=admin" CreatedUtc="2013-11-22T10:27:57.7066182Z" PublishedUtc="2013-11-22T10:27:57.7296195Z" ModifiedUtc="2013-11-22T10:27:57.7356199Z" />
        </Vehicle>
        <Vehicle Id="" Status="Published">
            <VehiclePart Name="Fiat Doblò" VehicleRole="2" Identification="DX 444 BL " RadioCode="051" StartKm="0" Note="" StartDate="2010-01-27T00:00:00" EndDate="" Active="true" />
            <CommonPart Owner="/User.UserName=admin" CreatedUtc="2013-11-22T10:27:57.7066182Z" PublishedUtc="2013-11-22T10:27:57.7296195Z" ModifiedUtc="2013-11-22T10:27:57.7356199Z" />
        </Vehicle>
    </Data>
</Orchard>

Отредактировано:

По запросу это код миграции, который создает структуру БД.

        SchemaBuilder.CreateTable(
            "VehiclePartRecord",
            table => table
                         .ContentPartRecord()
                         .Column<string>("Name", c => c.WithLength(25))
                         .Column("VehicleRole", DbType.Byte)
                         .Column<string>("Identification", c => c.WithLength(12))
                         .Column<string>("RadioCode", c => c.WithLength(5))
                         .Column<int>("StartKm")
                         .Column<string>("Note", c => c.WithLength(255))
                         .Column<DateTime>("StartDate")
                         .Column<DateTime>("EndDate")
                         .Column("Active", DbType.Boolean)
            );


        ContentDefinitionManager.AlterPartDefinition("VehiclePart",
                                                     builder => builder.Attachable());

        ContentDefinitionManager.AlterTypeDefinition(
            "Vehicle",
            cfg => cfg
                       .WithPart("VehiclePart")
                       .WithPart("CommonPart", p => p.WithSetting("OwnerEditorSettings.ShowOwnerEditor", "false"))
                       .Creatable(false)
            );

person manudea    schedule 22.11.2013    source источник
comment
Похоже, ваша EndDate не может быть обнулена. Когда первый импорт будет выполнен, он должен вызвать исключение в базе данных. Не могли бы вы заполнить это поле и попробовать еще раз?   -  person jmgomez    schedule 24.11.2013
comment
Спасибо за предложение. Я добавил значение во все поля startdate. Все поля теперь имеют значение. Ошибки не зарегистрированы. Все то же поведение: импортируется только последний. Я собираюсь попробовать импортировать другой тип детали и посмотреть, остается ли проблема такой же.   -  person manudea    schedule 25.11.2013
comment
Не могли бы вы отредактировать свой ответ, показав миграцию и данные, хранящиеся в базе данных?   -  person jmgomez    schedule 25.11.2013
comment
Я предполагаю, что вы имели в виду EndDate   -  person jmgomez    schedule 25.11.2013
comment
Да... я бы сказал EndDate... да, даты окончания и начала имеют допустимое значение...   -  person manudea    schedule 26.11.2013
comment
База данных в настоящее время пуста... Я удалил все автомобили...   -  person manudea    schedule 26.11.2013


Ответы (1)


Я попробовал код, и проблема в идентификаторе. Идентификатор не должен быть пустым, а также должен выглядеть примерно так: Id="/Identifier=3cf393fcbdea4c4a9e881e74ce177735.

С вашим идентификатором словарь всегда имеет один и тот же ключ, и он переопределяет последний. Я никогда раньше не использовал модуль импорта/экспорта, но я предполагаю, что эти идентификаторы были установлены вами.

Если вы хотите узнать об этом больше, взгляните на строку 81 в DataRecipeHandler.

person jmgomez    schedule 26.11.2013
comment
Ваше предложение указало мне правильное направление. Это не очень хорошо задокументировано, но для импорта/экспорта типа, к которому не подключен автомаршрут, следует добавить к нему идентификационную часть, затем эта часть создает уникальный идентификатор, используемый при импорте. Я не вижу строку 81 RecipeStepExceutor, потому что мой источник останавливается на строке 70... - person manudea; 27.11.2013
comment
Я решил выполнить свою пользовательскую команду импорта вместо того, чтобы пытаться сопоставить сгенерированный сложный xml ... в любом случае ваш ответ был полезен, поэтому я отмечаю его как ответ, поскольку другие могут найти его полезным. Хорошего дня. - person manudea; 27.11.2013
comment
Для других заинтересованных в создании пользовательской команды импорта посмотрите здесь: sarasota.me/blog/ - person manudea; 27.11.2013
comment
upps извините, я имел в виду DataRecipeHandler вместо RecipeStepExecutor. Да, для ввода пользовательских данных лучше сделать команду. На самом деле я делаю это в проекте клиента, около 100 тыс. строк данных из файлов Excel. И тебе хорошего дня :) - person jmgomez; 27.11.2013