EF Code First: обработка объекта как сложного типа (денормализация) - PullRequest
2 голосов
/ 31 мая 2011

Я использую EF 4.1 Code First и создаю настраиваемую утилиту для анализа / импорта больших файлов с разделителями. Каждая строка в файле может содержать данные для нескольких объектов.

Точные данные и формат файла будут неизвестны во время сборки (он настраивается по-разному для каждого клиента), поэтому я делаю его настраиваемым.

Пример модели (упрощенно)

public class Contact {
    public int Id { get; set;}
    public string Name { get; set; }
}

public class Account {
    public int Id { get; set; }
    public decimal Balance { get; set; }
    public bool IsOpen { get; set; }
}

В зависимости от клиента файл может содержать контактную информацию, информацию об учетной записи или и то, и другое. Из-за размера этих файлов (тонны записей) мы должны использовать SqlBulkCopy для загрузки данных. Во время компиляции также неизвестно, какие именно правила будут применяться к данным (изменения проверки клиентом и т. Д.)

Я хочу иметь таблицу и класс, например ImportRecord, для хранения импортированных данных. Мой текущий рабочий класс выглядит так:

public class ImportRecord {
    public string Contact_Name { get; set; }
    public decimal Account_Balance { get; set; }
    public bool Account_IsOpen { get; set; }
}

Проблема здесь в том, что когда мы добавляем / меняем поля в классах модели, ImportRecord также должен быть изменен - ​​он дублирующий / менее чем идеальный. Для меня несколько важно, чтобы данные импорта находились в одной таблице, чтобы упростить импорт SqlBulkCopy.

Мой идеальный класс ImportRecord будет выглядеть так:

public class ImportRecord {
    public Contact Contact { get; set; }
    public Account Account { get; set; }
}

Но это просто создало бы таблицу с двумя внешними ключами (кроме жалоб на отсутствие свойств FK). Есть ли способ заставить классы сущностей вести себя как денормализованный, безключевой, сложный тип для ImportRecord? Я совершенно не прав?

Спасибо!

1 Ответ

4 голосов
/ 01 июня 2011

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

public class Context : DbContext
{
    public DbSet<Account> Accounts { get; set; }
    public DbSet<Contact> Contacts { get; set; }
    public DbSet<ImportRecord> ImportRecords { get; set; }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        base.OnModelCreating(modelBuilder);

        modelBuilder.ComplexType<ContactBase>();
        modelBuilder.ComplexType<AccountBase>();
    }
}

public class ContactBase
{
    public string Name { get; set; }
}

public class AccountBase
{
    public decimal Balance { get; set; }
    public bool IsOpen { get; set; }
}

public class Contact : ContactBase
{
    public int Id { get; set; }
}

public class Account : AccountBase
{
    public int Id { get; set; }
}

public class ImportRecord
{
    public int Id { get; set; }
    public ContactBase Contact { get; set; }
    public AccountBase Account { get; set; }
}
...