更新模型导致在使用带有实体框架的Effort时从DbContext中删除接口

时间:2015-09-18 17:43:45

标签: c# unit-testing entity-framework-6 effort

目前,我正在尝试将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; }
    }
}

问题是,如果我通过选择&#34;从数据库更新模型来更新.edmx文件......&#34;然后它将上下文文件重新生成为:

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项目,这样每次我从数据库更新模型时它都不会吹掉接口和重载的构造函数? TIA。

更新

由于该类是部分的,我只是确保将接口和重载的构造函数放在一个不自动生成的单独文件中。

更新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 个答案:

答案 0 :(得分:3)

是的,该类被定义为部分类。创建一个新文件,该文件也声明相同的分部类,并在那里添加其他方法。

对于丢失的[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; }    
    }
}

答案 1 :(得分:1)

谢谢@Robert McKee!这是我最终做的事情:

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,其中IHRADDbContext接口是Effort所必需的:

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;
        }
    }
}