Из обширного поиска в Google, похоже, я не первый, кто столкнулся с этой проблемой, но я не смог найти никого, кто смог бы удовлетворительно решить ее - я интегрируюсь с устаревшей базой данных, и я только попытка интеграции с одной таблицей (на данный момент), и все же мой первый запрос к этой модели занимает около 12 секунд или около того. Второй звонок почти мгновенный, как и ожидалось.
Ниже приведена полная настройка кода Entity Framework First:
public class PortalDatabase : DbContext
{
public DbSet<User> Users { get; set; }
public PortalDatabase():base("portalDatabase")
{
}
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
User.ConfigureEntity(modelBuilder.Entity<User>());
}
}
public class User
{
public int ID { get; set; }
public string FullName { get; set; }
/// <summary>
/// Internal representation of the IsDisabled flag. This should not be
/// written to; use <see cref="IsDisabled"/> instead.
/// </summary>
internal byte IsDisabledInternal { get; set; }
public bool IsDisabled
{
get { return Convert.ToBoolean(this.IsDisabledInternal); }
set { this.IsDisabledInternal = Convert.ToByte(value); }
}
public int LoginAttempts { get; set; }
public string EmailAddress { get; set; }
public string Password { get; set; }
internal static void ConfigureEntity(EntityTypeConfiguration<User> entity)
{
entity.ToTable("Users");
entity.Property(model => model.ID)
.HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity)
.HasColumnName("UserID");
entity.Property(model => model.FullName)
.HasColumnName("UserName");
entity.Property(model => model.IsDisabledInternal)
.HasColumnName("AccountLocked");
entity.Ignore(model => model.IsDisabled);
entity.Property(model => model.LoginAttempts)
.HasColumnName("LoginAttempts");
entity.Property(model => model.EmailAddress)
.HasColumnName("EmailAddress");
entity.Property(model => model.Password)
.HasColumnName("Password");
}
}
Выполнение этого примера кода занимает 8-12 секунд:
PortalDatabase database = new PortalDatabase();
IEnumerable<User> users = from user in database.Users
where user.ID == 66
select user;
Я понимаю, что эта проблема связана с генерацией метаданных, которая выполняется только один раз, что согласно комментарию ScottGu"значительно повышает производительность":
Библиотека «сначала код» использует тот же базовый EF, что и традиционный подход - поэтому характеристики производительности должны быть примерно одинаковыми. Библиотека «сначала кодируй» также включает в себя некоторые смарт-коды, так что метаданные, которые извлекаются для сопоставления с базой данных, кэшируются - так что их нужно вычислять только один раз (что значительно повышает производительность).
Но средняя производительность, которую я описал? Я не могу себе представить, что для выполнения простого запроса было бы приемлемо потратить 12 секунд на выполнение простого запроса. Я неправильно его понимаю? Сохраняется ли кэш метаданных в течение, например, пула приложений IIS? Это может быть в какой-то мере приемлемо, хотя вряд ли идеально.
Если бы я сначала не использовал код, то я бы смог использовать EdmGen.exe для генерации моих представлений , что, как я понимаю, значительно ускорило бы мое приложение. Есть ли эквивалент при разработке моей модели с использованием кода сначала?
Обновление от 14 февраля 2012 : Благодаря сообщению Павла , я смог создать свои просмотры. К сожалению, это не изменило скорость создания нового экземпляра PortalDatabase, который по-прежнему занимает столько же времени. Я знаю, что представления используются, потому что я установил точку останова в конструкторе, но это ни на что не влияет.