Обновление модели приводит к удалению интерфейса из DbContext при использовании Effort с Entity Framework
В настоящее время я пытаюсь использовать Effort ( https://effort.codeplex.com/) с моим решением Entity Framework 6, чтобы разрешить модульное тестирование без подключения к базе данных (см. http://www.codeproject.com/Articles/460175/Two-strategies-for-testing-Entity-Framework-Effort. Все работает в моем проекте, где это DbContext
с интерфейсом и перегруженными конструкторами, необходимыми для Effort:
namespace Cssd.IT.PortalIntegration.DataAccess.HR.Dao
{
using System;
using System.Data.Common;
using System.Data.Entity;
using System.Data.Entity.Infrastructure;
public partial class HRADDbContext : DbContext, IHRADDbContext
{
public HRADDbContext() : base("name=HRADDbContext")
{
}
public HRADDbContext(string nameOrConnectionString)
: base(nameOrConnectionString)
{
this.Configuration.LazyLoadingEnabled = false;
}
public HRADDbContext(DbConnection connection)
: base(connection, true)
{
this.Configuration.LazyLoadingEnabled = false;
}
public virtual DbSet<CCS_DEPT_TBL> CCS_DEPT_TBL { get; set; }
public virtual DbSet<CCS_HR_AD_SYNC> CCS_HR_AD_SYNC { get; set; }
}
}
Проблема в том, если я обновлю .edmx
файл, выбрав "Обновить модель из базы данных...", затем он создает файл контекста следующим образом:
namespace Cssd.IT.PortalIntegration.DataAccess.HR.Dao
{
using System;
using System.Data.Common;
using System.Data.Entity;
public partial class HRADDbContext : DbContext
{
public HRADDbContext() : base("name=HRADDbContext")
{
}
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
throw new UnintentionalCodeFirstException();
}
public virtual DbSet<CCS_DEPT_TBL> CCS_DEPT_TBL { get; set; }
public virtual DbSet<CCS_HR_AD_SYNC> CCS_HR_AD_SYNC { get; set; }
}
}
Поэтому я должен вернуться и вручную обновить выше Context.cs
подавать каждый раз. Кроме того, удаляет [Key]
от POCO CCS_DEPT_TBL
файл.
Есть ли способ настроить мой проект Entity Framework, чтобы он не сдул интерфейс и перегруженные конструкторы каждый раз, когда я обновляю модель из базы данных? ТИА.
ОБНОВИТЬ:
Поскольку класс является частичным, я просто гарантирую, что интерфейс и перегруженные конструкторы помещаются в отдельный файл, который не генерируется автоматически.
ОБНОВЛЕНИЕ 2:
ОК, понял, просто добавил это в отдельный файл, взяв DEPTID
из оригинала POCO
файл, но он все еще помещает это DEPTID
в сгенерированном файле, поэтому после обновления сборка прерывается, потому что есть два DEPTID
значения в одном классе:
namespace Cssd.IT.PortalIntegration.DataAccess.HR.Dao
{
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
public partial class CCS_DEPT_TBL
{
[Key]
public string DEPTID { get; set; }
}
}
Итак, как я могу предотвратить его генерацию DEPTID
в сгенерированном файле класса, так как он уже находится в вышеуказанном частичном файле класса?
2 ответа
Да, класс определяется как частичный класс. Создайте новый файл, который также объявляет тот же частичный класс, и добавьте туда дополнительные методы.
Что касается потери атрибута [Key], вы можете попробовать использовать атрибут MetadataType и поместить все свои метаданные туда.
namespace Cssd.IT.PortalIntegration.DataAccess.HR.Dao
{
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
[MetadataType(typeof(CCS_DEPT_TBL_Meta))]
public partial class CCS_DEPT_TBL
{
... Your additional constructors and methods here ...
}
public class CCS_DEPT_TBL_Meta
{
[Key]
public string DEPTID { get; set; }
}
}
Спасибо @ Роберт Макки! Вот что я в итоге сделал:
CCS_DEPT_TBL_Key.cs:
namespace Cssd.IT.PortalIntegration.DataAccess.HR.Dao
{
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
[MetadataType(typeof(CCS_DEPT_TBL_Meta))]
public partial class CCS_DEPT_TBL
{
}
public class CCS_DEPT_TBL_Meta
{
[Key]
public string DEPTID { get; set; }
}
}
CCS_DEPT_TBL.cs:
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated from a template.
//
// Manual changes to this file may cause unexpected behavior in your application.
// Manual changes to this file will be overwritten if the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
namespace Cssd.IT.PortalIntegration.DataAccess.HR.Dao
{
using System;
using System.Collections.Generic;
public partial class CCS_DEPT_TBL
{
// This table in SQL Server does not have a primary key, it just has an index
public string DEPTID { get; set; }
public string DESCR { get; set; }
public System.DateTime EFFDT { get; set; }
public string EFF_STATUS { get; set; }
public Nullable<System.DateTime> LASTUPDDTTM { get; set; }
}
}
HRModel.Context.cs: HRADDbContext на самом деле является объектами с первой базой данных, но есть три других файла *.edmx, которые являются объектами с первым кодом в том же проекте, поэтому закомментировал это исключение в HRModel.Context.cs, потому что это не так т применяется. Вероятно, было бы лучше разделить объекты базы данных в отдельный проект, чтобы это исключение не создавалось при обновлении модели базы данных.
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated from a template.
//
// Manual changes to this file may cause unexpected behavior in your application.
// Manual changes to this file will be overwritten if the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
namespace Cssd.IT.PortalIntegration.DataAccess.HR.Dao
{
using System;
using System.Data.Entity;
using System.Data.Entity.Infrastructure;
public partial class HRADDbContext : DbContext
{
public HRADDbContext()
: base("name=HRADDbContext")
{
}
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
//throw new UnintentionalCodeFirstException();
}
public virtual DbSet<CCS_DEPT_TBL> CCS_DEPT_TBL { get; set; }
public virtual DbSet<CCS_HR_AD_SYNC> CCS_HR_AD_SYNC { get; set; }
}
}
HRADDbContext.cs, где для Effort необходим интерфейс IHRADDbContext:
using System;
using System.Data.Common;
using System.Data.Entity;
using System.Data.Entity.Infrastructure;
namespace Cssd.IT.PortalIntegration.DataAccess.HR.Dao
{
/// <summary>
/// Added interface here so that it does not get removed when updating
/// model from the database on code generation.
/// </summary>
partial class HRADDbContext : IHRADDbContext
{
public HRADDbContext(string nameOrConnectionString)
: base(nameOrConnectionString)
{
this.Configuration.LazyLoadingEnabled = false;
}
public HRADDbContext(DbConnection connection)
: base(connection, true)
{
this.Configuration.LazyLoadingEnabled = false;
}
}
}