为什么实体框架不尊重我的数据注释?

时间:2015-08-31 16:10:54

标签: c# asp.net .net entity-framework ef-code-first

为什么实体框架不尊重我的数据注释?

一点背景:我刚开始一份新工作,我的任务是将实体框架添加到ASP.net项目中。项目结构如下:     Data.csproj - >有我新添加的代码优先实体框架代码。这个项目将容纳我们的模型     MVC.csproj - > ClassLibrary包含MVC结构的所有控制器。该项目目前充斥着MVC领域。我已经添加了OWIN以及UserStore,UserManager和SignInManager     Web.vbproj - >这是一个Asp.Net Web表单项目,它混合了MVC和webforms代码。根据我的老板,系统架构师,计划是除了html视图,css和javascript之外什么都没有。我们目前正在将这个项目从asp.net webforms迁移到前面提到的MVC结构。

我正在使用EntityFramework v6.1.1

在Data.csproj项目中,我定义了以下实体:

[Table("Terminals", Schema = "dbo")]
public class TerminalEx
{
    #region Constructors
    public TerminalEx()
    {

    }
    #endregion

    #region Public Properties
    [Key]
    public int TerminalId { get; set; }

    public string License { get; set; }

    [Column("TerminalName")]
    public string Name { get; set; }

    public string RootPublicDomainAddress { get; set; }
    public string CompanyName { get; set; }
    public int TimeZoneId { get; set; }
    public string Zip { get; set; }
    public string DispatchEmail { get; set; }

    [Column("useAutoAddlDrvPmt")]
    public byte UseAutoAddDriverPayment { get; set; }

    public byte UseTerminalAutoAssignment { get; set; }
    public byte UseMapCodes { get; set; }

    [Column("OEautoPopulateAccountNo")]
    public byte AutoPopulateAccountNumberForOrderEntry { get; set; }

    [Column("OEautoPopulateAddresses")]
    public byte AutoPopulateAddressesForOrderEntry { get; set; }
    #endregion
}

这是我的DbContext:

public class XceleratorContext : DbContext
{
    public static void DoTest()
    {
        XceleratorContext db = null;
        try
        {
            db = new XceleratorContext();
            var bleh = db.Terminals.ToList();

            foreach (TerminalEx term in bleh)
            {
                System.Diagnostics.Debug.WriteLine(term.TerminalId);
                System.Diagnostics.Debug.WriteLine(term.Name);
            }
        }
        catch (Exception ex)
        {
            System.Diagnostics.Debug.WriteLine(ex.ToString());
            throw;
        }
        finally
        {
            if (db != null)
            {
                db.Dispose();
                db = null;
            }
        }
    }

    #region Contructors
    public XceleratorContext()
        : base(ConfigurationManager.AppSettings["ConnectionString"])
    {
        Database.SetInitializer<XceleratorContext>(null);
        this.Database.Log += WriteLog;
    }

    private void WriteLog(string obj)
    {
        System.Diagnostics.Debug.WriteLine(obj);
    }
    #endregion

    #region Public Properties
    public virtual DbSet<TerminalEx> Terminals { get; set; }
    #endregion

    #region Encapsulation of DbSets
    public T Add<T>(T entity) where T : class
    {
        return Set<T>().Add(entity);
    }

    public T Attach<T>(T entity) where T : class
    {
        Set<T>().Attach(entity);
        Entry<T>(entity).State = EntityState.Modified;
        return entity;
    }

    public T Detach<T>(T entity) where T : class
    {
        Entry<T>(entity).State = EntityState.Detached;
        return entity;
    }

    public T Remove<T>(T entity) where T : class
    {
        if (Entry<T>(entity).State == EntityState.Detached)
        {
            Entry<T>(entity).State = EntityState.Deleted;
            return Entry<T>(entity).Entity;
        }
        else
            return Set<T>().Remove(entity);
    }
    #endregion

    #region Method Overrides
    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.Entity<EFUser>();
        var terminalConfig = modelBuilder.Entity<TerminalEx>();

        //terminalConfig.Map(b => 
        //{
        //    b.Property(c => c.Name).HasColumnName("TerminalName");
        //    b.Property(c => c.UseAutoAddDriverPayment).HasColumnName("useAutoAddlDrvPmt");
        //    b.Property(c => c.AutoPopulateAccountNumberForOrderEntry).HasColumnName("OEautoPopulateAccountNo");
        //    b.Property(c => c.AutoPopulateAddressesForOrderEntry).HasColumnName("OEautoPopulateAddresses");                
        //}).ToTable("Terminals", "dbo").HasKey(d => d.TerminalId);

        // base.OnModelCreating(modelBuilder);
    }        
    #endregion

    #region Stored Proicedure Calls
    public IEnumerable<EFUser> GetUser(int? id = null, string userName = null, string passwordHash = null)
    {
        return this.Database.SqlQuery<EFUser>(
            " exec dbo.GetUser @id, @userName, @passwordHash ", 
            GetSqlParameter("id", System.Data.SqlDbType.Int, value: id),
            GetSqlParameter("userName", System.Data.SqlDbType.NVarChar, 100, userName),
            GetSqlParameter("passwordHash", System.Data.SqlDbType.NVarChar, 100, passwordHash));            
    }
    #endregion

    #region Private Methods
    private static SqlParameter GetSqlParameter<T>(string name, System.Data.SqlDbType type, int? size = null, T? value = null) where T : struct
    {
        var res = new SqlParameter(name, type) { Value = value ?? (object)DBNull.Value };

        if (size.HasValue)
            res.Size = size.Value;

        return res;
    }

    private static SqlParameter GetSqlParameter(string name, System.Data.SqlDbType type, int size, string value)
    {
        return new SqlParameter(name, type, size) { Value = value ?? (object)DBNull.Value };
    }
    #endregion
}

最后在Web.vbproj里面是index.opx.vb的Page_Load

Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load

    Xcelerator.Data.BizObjects.XceleratorContext.DoTest()

End Sub

我的问题是我收到以下错误。我通过创建一个新的asp.net webforms VB proj并在索引页面的页面加载上调用相同的方法来测试我的代码,并且工作正常。我已经从web.vbpoj中删除了尽可能多的代码,引用和包,但我仍然得到相同的错误。出于某些原因,仅在此Web.vbproj中,代码优先实体框架不尊重我的数据注释。

  

发现了System.Data.Entity.Core.EntityCommandExecutionException   HResult = -2146232004消息=执行时发生错误   命令定义。有关详细信息,请参阅内部异常   Source = EntityFramework StackTrace:          在System.Data.Entity.Core.EntityClient.Internal.EntityCommandDefinition.ExecuteStoreCommands(EntityCommand)   entityCommand,CommandBehavior行为)          at System.Data.Entity.Core.Objects.Internal.ObjectQueryExecutionPlan.Execute [TResultType](ObjectContext   context,ObjectParameterCollection parameterValues)          在System.Data.Entity.Core.Objects.ObjectQuery 1.<>c__DisplayClass3.<GetResults>b__2() at System.Data.Entity.Core.Objects.ObjectContext.ExecuteInTransaction[T](Func 1   func,IDbExecutionStrategy executionStrategy,Boolean   startLocalTransaction,Boolean releaseConnectionOnSuccess)          在System.Data.Entity.Core.Objects.ObjectQuery 1.<>c__DisplayClass3.<GetResults>b__1() at System.Data.Entity.SqlServer.DefaultSqlExecutionStrategy.Execute[TResult](Func 1   操作)          在System.Data.Entity.Core.Objects.ObjectQuery 1.GetResults(Nullable 1   forMergeOption)          在System.Data.Entity.Core.Objects.ObjectQuery 1.<System.Collections.Generic.IEnumerable<T>.GetEnumerator>b__0() at System.Lazy 1.CreateValue()          在System.Lazy 1.LazyInitValue() at System.Lazy 1.get_Value()          在System.Data.Entity.Internal.LazyEnumerator 1.MoveNext() at System.Collections.Generic.List 1..ctor(IEnumerable 1 collection) at System.Linq.Enumerable.ToList[TSource](IEnumerable 1来源)          在C:\ svonaRepo \ XceleratorLocal中的Xcelerator.Data.BizObjects.XceleratorContext.DoTest() -   复制\ Xcelerator.Data \ BizObjects \ XceleratorContext.cs:第22行   InnerException:System.Data.SqlClient.SqlException          的HResult = -2146232060          消息=无效的对象名称&#39; dbo.TerminalExes&#39;。          Source = .Net SqlClient数据提供程序          错误码= -2146232060          类= 16          LineNumber上= 1          数= 208          过程=&#34;&#34;          服务器= KSS-DT18          状态= 1          堆栈跟踪:               在System.Data.SqlClient.SqlConnection.OnError(SqlException异常,   Boolean breakConnection,Action 1 wrapCloseInAction) at System.Data.SqlClient.SqlInternalConnection.OnError(SqlException exception, Boolean breakConnection, Action 1 wrapCloseInAction)               在System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning(TdsParserStateObject)   stateObj,Boolean callerHasConnectionLock,Boolean asyncClose)               在System.Data.SqlClient.TdsParser.TryRun(RunBehavior runBehavior,SqlCommand cmdHandler,SqlDataReader dataStream,   BulkCopySimpleResultSet bulkCopyHandler,TdsParserStateObject   stateObj,布尔&amp; dataReady)               在System.Data.SqlClient.SqlDataReader.TryConsumeMetaData()               在System.Data.SqlClient.SqlDataReader.get_MetaData()               在System.Data.SqlClient.SqlCommand.FinishExecuteReader(SqlDataReader ds,   RunBehavior runBehavior,String resetOptionsString)               在System.Data.SqlClient.SqlCommand.RunExecuteReaderTds(CommandBehavior   cmdBehavior,RunBehavior runBehavior,Boolean returnStream,Boolean   async,Int32超时,任务&amp; task,Boolean asyncWrite,SqlDataReader   ds,Boolean describeParameterEncryptionRequest)               在System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior   cmdBehavior,RunBehavior runBehavior,Boolean returnStream,String   方法,TaskCompletionSource 1 completion, Int32 timeout, Task& task, Boolean asyncWrite) at System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method) at System.Data.SqlClient.SqlCommand.ExecuteReader(CommandBehavior behavior, String method) at System.Data.SqlClient.SqlCommand.ExecuteDbDataReader(CommandBehavior behavior) at System.Data.Common.DbCommand.ExecuteReader(CommandBehavior behavior) at System.Data.Entity.Infrastructure.Interception.DbCommandDispatcher.<>c__DisplayClassb.<Reader>b__8() at System.Data.Entity.Infrastructure.Interception.InternalDispatcher 1.Dispatch [TInterceptionContext,TResult](Func 1 operation, TInterceptionContext interceptionContext, Action 1   执行,执行Action`1)               在System.Data.Entity.Infrastructure.Interception.DbCommandDispatcher.Reader(DbCommand)   command,DbCommandInterceptionContext interceptionContext)               在System.Data.Entity.Internal.InterceptableDbCommand.ExecuteDbDataReader(CommandBehavior)   行为)               在System.Data.Common.DbCommand.ExecuteReader(CommandBehavior行为)               在System.Data.Entity.Core.EntityClient.Internal.EntityCommandDefinition.ExecuteStoreCommands(EntityCommand)   entityCommand,CommandBehavior行为)          的InnerException:

2 个答案:

答案 0 :(得分:0)

这部分代码说:“我想用POCO做Fluent Code First”,也就是说,我的POCO没有注释,这里是我想要的映射自定义。

然后,您继续对映射进行无自定义。因此,您将获得默认映射。

#region Method Overrides
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
    modelBuilder.Entity<EFUser>();
    var terminalConfig = modelBuilder.Entity<TerminalEx>();

    //terminalConfig.Map(b => 
    //{
    //    b.Property(c => c.Name).HasColumnName("TerminalName");
    //    b.Property(c => c.UseAutoAddDriverPayment).HasColumnName("useAutoAddlDrvPmt");
    //    b.Property(c => c.AutoPopulateAccountNumberForOrderEntry).HasColumnName("OEautoPopulateAccountNo");
    //    b.Property(c => c.AutoPopulateAddressesForOrderEntry).HasColumnName("OEautoPopulateAddresses");                
    //}).ToTable("Terminals", "dbo").HasKey(d => d.TerminalId);

    // base.OnModelCreating(modelBuilder);
}        
#endregion

只需删除DbContext的那一部分,一切都会好的。

答案 1 :(得分:0)

我终于找到了问题。 Web.vbproj项目包含项目中包含的NuGet包文件夹。通过从项目中排除文件夹,我的EF代码/方法按预期工作。