本文介绍了EF代码优先 - 列名称无效的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述



所以我的上下文是:

  public partial class FeesDbContext:DisconnectedEntityContext 
{

public DbSet< Currency>货币{get; set;}

public DbSet< FeeLevel> FeeLevels {get; set;}

public DbSet< FeeLevelDetail> FeeLevelDetails {get; set;}

public DbSet< FeeType> FeeTypes {get; set;}

public DbSet< MemberFeeDiscountLevel> MemberFeeDiscountLevels {get; set;}

public FeesDbContext()
:base(FeesDb){}

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Configurations.Add FeeLevelMap());
modelBuilder.Configurations.Add(new FeeLevelDetailMap());
modelBuilder.Configurations.Add(new FeeTypeMap());
modelBuilder.Configurations.Add(new CurrencyMap());
modelBuilder.Configurations.Add(new MemberFeeDiscountLevelMap());
}

public static void ApplyChanges< TEntity>(TEntity root)
其中TEntity:class,IObjectWithState
{
using(var context = new FeesDbContext ())
{
context.Set< TEntity>()。Add(root);
foreach(context.ChangeTracker.Entries< IObjectWithState>()中的var entry)
{
IObjectWithState stateInfo = entry.Entity;
entry.State = ConvertState(stateInfo.State);
}
context.SaveChanges();
}
}
}

POCO是: p>

  public partial class MemberFeeDiscountLevel:AbstractState 
{

public long MemberFeeDiscountLevelId {get;组; }
public System.Guid MemberId {get;组; }
public short MemberAsType {get;组; }
public long FeeDiscountLevelId {get;组; }
public System.DateTime FeeDiscountLevelAppliedDate {get;组; }
public Nullable< System.DateTime> FeeDiscountLevelExpiresDate {get;组; }
public Nullable< long> FallbackFeeDiscountLevelId {get;组; }
public System.Guid UserId {get;组; }
public System.DateTime LastModified {get;组;


public MemberFeeDiscountLevel(ObjectState state):base(state){}

public MemberFeeDiscountLevel()
{
}
}

它的映射是:

  public class MemberFeeDiscountLevelMap:EntityTypeConfiguration< MemberFeeDiscountLevel> 
{
public MemberFeeDiscountLevelMap()
{
//主键
this.HasKey(t => t.MemberFeeDiscountLevelId);

this.Ignore(t => t.State);

//属性
// Table&列映射
this.ToTable(MemberFeeDiscountLevel);
this.Property(t => t.MemberFeeDiscountLevelId).HasColumnName(MemberFeeDiscountLevelId);
this.Property(t => t.MemberId).HasColumnName(MemberId);
this.Property(t => t.MemberAsType).HasColumnName(MemberAsType);
this.Property(t => t.FeeDiscountLevelId).HasColumnName(FeeDiscountLevelId);
this.Property(t => t.FeeDiscountLevelAppliedDate).HasColumnName(FeeDiscountLevelAppliedDate);
this.Property(t => t.FeeDiscountLevelExpiresDate).HasColumnName(FeeDiscountLevelExpiresDate);
this.Property(t => t.FallbackFeeDiscountLevelId).HasColumnName(FallbackFeeDiscountLevelId);
this.Property(t => t.UserId).HasColumnName(UserId);
this.Property(t => t.LastModified).HasColumnName(LastModified);
}
}

数据库表是:





&p没有关系。然而,EF正在生成以下SQL:

  exec sp_executesql N'INSERT [dbo]。[MemberFeeDiscountLevel]([MemberId],[ MemberAsType],[FeeDiscountLevelId],[FeeDiscountLevelAppliedDate],[FeeDiscountLevelExpiresDate],[FallbackFeeDiscountLevelId],[UserId],[LastModified],[FeeLevel_LevelId])
VALUES(@ 0,@ 1,@ 2,@ 3,

FROM [dbo]。[MemberFeeDiscountLevel]
WHERE @@ ROWCOUNT> 0 AND [MemberFeeDiscountLevelId] = scope_identity()',N'@ 0 uniqueidentifier,@ 1 smallint,@ 2 bigint,@ 3 datetime2(7),@ 4 datetime2(7),@ 5 bigint,@ 6 uniqueidentifier,@ 7 datetime2 (7),@ 8 int',@ 0 ='DAF771D1-079F-4743-B5C7-FD0FA1C63E19',@ 1 = 0,@ 2 = 1012,@ 3 ='2014-01-24 12:05:36.0608347' @ 4 ='2014-02-01 00:00:00',@ 5 = 1018,@ 6 ='EEDF2C83-2123-4B1C-BF8D-BE2D2FA26D09',@ 7 ='2014-01-24 12:05:36.0608347 '
go

更新:



创建一个新的Fees2DbContext剥离其他DbSets修复问题....但我不知道为什么...这些类/集都没有与有问题的类有关。 / p>

  public partial class Fees2DbContext:DisconnectedEntityContext 
{
public DbSet< MemberFeeDiscountLevel> MemberFeeDiscountLevels {get;组;

public Fees2DbContext()
:base(FeesDb){}

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Configurations.Add(new MemberFeeDiscountLevelMap());
}

public static void ApplyChanges< TEntity>(TEntity root)
其中TEntity:class,IObjectWithState
{
using(var context = new Fees2DbContext ())
{
context.Set< TEntity>()。Add(root);
foreach(context.ChangeTracker.Entries< IObjectWithState>()中的var entry)
{
IObjectWithState stateInfo = entry.Entity;
entry.State = ConvertState(stateInfo.State);
}
context.SaveChanges();
}
}
}

更新2:

  public partial class FeeLevel:AbstractState 
{
public FeeLevel()
{
this.FeeLevelDetails = new List< FeeLevelDetail>();
this.MemberFeeDiscountLevels = new List< MemberFeeDiscountLevel>();
}

public long LevelId {get;组; }

public string LevelName {get;组; }

public int CurrencyId {get;组; }

public System.DateTime LastModified {get;组; }

public bool IsSystemOwned {get;组; }

public System.Guid UserId {get;组; }

public virtual货币货币{get;组; }

[ScriptIgnore]
public virtual ICollection< FeeLevelDetail> FeeLevelDetails {get;组; }

public virtual ICollection< MemberFeeDiscountLevel> MemberFeeDiscountLevels {get;组; }
}

public class FeeLevelMap:EntityTypeConfiguration< FeeLevel>
{
public FeeLevelMap()
{
//主键
this.HasKey(t => t.LevelId);

this.Ignore(t => t.State);

//属性
this.Property(t => t.LevelId);
// .HasDatabaseGeneratedOption(DatabaseGeneratedOption.None);

this.Property(t => t.LevelName)
.IsRequired()
.HasMaxLength(50);

// Table&列映射
this.ToTable(FeeLevel);
this.Property(t => t.LevelId).HasColumnName(LevelId);
this.Property(t => t.LevelName).HasColumnName(LevelName);
this.Property(t => t.CurrencyId).HasColumnName(CurrencyId);
this.Property(t => t.LastModified).HasColumnName(LastModified);
this.Property(t => t.UserId).HasColumnName(UserId);

//关系
this.HasRequired(t => t.Currency)
.WithMany(t => t.FeeLevels)
.HasForeignKey(d = d.CurrencyId);

}
}


解决方案

FeeLevel.MemberFeeDiscountLevels 是一个导航属性,它在 FeeLevel 之间引入了一对多的关系, code> MemberFeeDiscountLevel :A FeeLevel 可以有很多 MemberFeeDiscountLevels 这意味着同时, MemberFeeDiscountLevel 有一个 FeeLevel 。虽然您在 MemberFeeDiscountLevel 中没有导航和外键属性,但数据库必须在 MemberFeeDiscountLevel 中具有外键表为了建模这种关系。 EF假定默认的FK名称为相关实体名称+下划线+主键名称= FeeLevel_LevelId 。因为你的数据库表没有这个列,你会得到例外。


Im getting an error "Invalid column name 'FeeLevel_LevelId' which makes absolutely no sense considering all properties are simple types and there is no FeeLevel nor a LevelId object in this object.

So my context is:

  public partial class FeesDbContext : DisconnectedEntityContext
    {

        public DbSet<Currency> Currencies { get; set; }

        public DbSet<FeeLevel> FeeLevels { get; set; }

        public DbSet<FeeLevelDetail> FeeLevelDetails { get; set; }

        public DbSet<FeeType> FeeTypes { get; set; }

        public DbSet<MemberFeeDiscountLevel> MemberFeeDiscountLevels { get; set; }

        public FeesDbContext()
            : base("FeesDb") { }

        protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
            modelBuilder.Configurations.Add(new FeeLevelMap());
            modelBuilder.Configurations.Add(new FeeLevelDetailMap());
            modelBuilder.Configurations.Add(new FeeTypeMap());
            modelBuilder.Configurations.Add(new CurrencyMap());
            modelBuilder.Configurations.Add(new MemberFeeDiscountLevelMap());
        }

        public static void ApplyChanges<TEntity>(TEntity root)
                    where TEntity : class, IObjectWithState
        {
            using (var context = new FeesDbContext())
            {
                context.Set<TEntity>().Add(root);
                foreach (var entry in context.ChangeTracker.Entries<IObjectWithState>())
                {
                    IObjectWithState stateInfo = entry.Entity;
                    entry.State = ConvertState(stateInfo.State);
                }
                context.SaveChanges();
            }
        }
}

The POCO is:

public partial class MemberFeeDiscountLevel : AbstractState
    {

        public long MemberFeeDiscountLevelId { get; set; }
        public System.Guid MemberId { get; set; }
        public short MemberAsType { get; set; }
        public long FeeDiscountLevelId { get; set; }
        public System.DateTime FeeDiscountLevelAppliedDate { get; set; }
        public Nullable<System.DateTime> FeeDiscountLevelExpiresDate { get; set; }
        public Nullable<long> FallbackFeeDiscountLevelId { get; set; }
        public System.Guid UserId { get; set; }
        public System.DateTime LastModified { get; set; }


        public MemberFeeDiscountLevel(ObjectState state) : base(state) { }

        public MemberFeeDiscountLevel()
        {
        }
    }

It's mapping is:

  public class MemberFeeDiscountLevelMap : EntityTypeConfiguration<MemberFeeDiscountLevel>
    {
        public MemberFeeDiscountLevelMap()
        {
            // Primary Key
            this.HasKey(t => t.MemberFeeDiscountLevelId);

            this.Ignore(t => t.State);

            // Properties
            // Table & Column Mappings
            this.ToTable("MemberFeeDiscountLevel");
            this.Property(t => t.MemberFeeDiscountLevelId).HasColumnName("MemberFeeDiscountLevelId");
            this.Property(t => t.MemberId).HasColumnName("MemberId");
            this.Property(t => t.MemberAsType).HasColumnName("MemberAsType");
            this.Property(t => t.FeeDiscountLevelId).HasColumnName("FeeDiscountLevelId");
            this.Property(t => t.FeeDiscountLevelAppliedDate).HasColumnName("FeeDiscountLevelAppliedDate");
            this.Property(t => t.FeeDiscountLevelExpiresDate).HasColumnName("FeeDiscountLevelExpiresDate");
            this.Property(t => t.FallbackFeeDiscountLevelId).HasColumnName("FallbackFeeDiscountLevelId");
            this.Property(t => t.UserId).HasColumnName("UserId");
            this.Property(t => t.LastModified).HasColumnName("LastModified");
        }
    }

The database table is:

and it has not relationships. Yet EF is generating the following SQL:

exec sp_executesql N'INSERT [dbo].[MemberFeeDiscountLevel]([MemberId], [MemberAsType], [FeeDiscountLevelId], [FeeDiscountLevelAppliedDate], [FeeDiscountLevelExpiresDate], [FallbackFeeDiscountLevelId], [UserId], [LastModified], [FeeLevel_LevelId])
VALUES (@0, @1, @2, @3, @4, @5, @6, @7, @8, NULL)
SELECT [MemberFeeDiscountLevelId]
FROM [dbo].[MemberFeeDiscountLevel]
WHERE @@ROWCOUNT > 0 AND [MemberFeeDiscountLevelId] = scope_identity()',N'@0 uniqueidentifier,@1 smallint,@2 bigint,@3 datetime2(7),@4 datetime2(7),@5 bigint,@6 uniqueidentifier,@7 datetime2(7),@8 int',@0='DAF771D1-079F-4743-B5C7-FD0FA1C63E19',@1=0,@2=1012,@3='2014-01-24 12:05:36.0608347',@4='2014-02-01 00:00:00',@5=1018,@6='EEDF2C83-2123-4B1C-BF8D-BE2D2FA26D09',@7='2014-01-24 12:05:36.0608347'
go

UPDATE:

Creating a new Fees2DbContext stripping out the other DbSets "fixes" the problem.... but I dont know why... none of these classes / sets are related to the class in question.

 public partial class Fees2DbContext : DisconnectedEntityContext
    {
        public DbSet<MemberFeeDiscountLevel> MemberFeeDiscountLevels { get; set; }

        public Fees2DbContext()
            : base("FeesDb") { }

        protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
            modelBuilder.Configurations.Add(new MemberFeeDiscountLevelMap());
        }

        public static void ApplyChanges<TEntity>(TEntity root)
                    where TEntity : class, IObjectWithState
        {
            using (var context = new Fees2DbContext())
            {
                context.Set<TEntity>().Add(root);
                foreach (var entry in context.ChangeTracker.Entries<IObjectWithState>())
                {
                    IObjectWithState stateInfo = entry.Entity;
                    entry.State = ConvertState(stateInfo.State);
                }
                context.SaveChanges();
            }
        }
    }

UPDATE 2:

       public partial class FeeLevel : AbstractState
        {
            public FeeLevel()
            {
                this.FeeLevelDetails = new List<FeeLevelDetail>();
                this.MemberFeeDiscountLevels = new List<MemberFeeDiscountLevel>();
            }

            public long LevelId { get; set; }

            public string LevelName { get; set; }

            public int CurrencyId { get; set; }

            public System.DateTime LastModified { get; set; }

            public bool IsSystemOwned { get; set; }

            public System.Guid UserId { get; set; }

            public virtual Currency Currency { get; set; }

            [ScriptIgnore]
            public virtual ICollection<FeeLevelDetail> FeeLevelDetails { get; set; }

            public virtual ICollection<MemberFeeDiscountLevel> MemberFeeDiscountLevels { get; set; }
        }

public class FeeLevelMap : EntityTypeConfiguration<FeeLevel>
    {
        public FeeLevelMap()
        {
            // Primary Key
            this.HasKey(t => t.LevelId);

            this.Ignore(t => t.State);

            // Properties
            this.Property(t => t.LevelId);
            // .HasDatabaseGeneratedOption(DatabaseGeneratedOption.None);

            this.Property(t => t.LevelName)
                .IsRequired()
                .HasMaxLength(50);

            // Table & Column Mappings
            this.ToTable("FeeLevel");
            this.Property(t => t.LevelId).HasColumnName("LevelId");
            this.Property(t => t.LevelName).HasColumnName("LevelName");
            this.Property(t => t.CurrencyId).HasColumnName("CurrencyId");
            this.Property(t => t.LastModified).HasColumnName("LastModified");
            this.Property(t => t.UserId).HasColumnName("UserId");

            // Relationships
            this.HasRequired(t => t.Currency)
                .WithMany(t => t.FeeLevels)
                .HasForeignKey(d => d.CurrencyId);

        }
    }
解决方案

FeeLevel.MemberFeeDiscountLevels is a navigation property and it introduces a one-to-many relationship between FeeLevel and MemberFeeDiscountLevel: A FeeLevel can have many MemberFeeDiscountLevels which means at the same time that a MemberFeeDiscountLevel has a single FeeLevel. Although you don't have a navigation and foreign key property in MemberFeeDiscountLevel the database must have a foreign key in the MemberFeeDiscountLevel table in order to model this relationship. EF assumes a default FK name as "related entity name+underscore+primary key name" = FeeLevel_LevelId. Because your database table doesn't have this column you get the exception.

这篇关于EF代码优先 - 列名称无效的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

05-31 03:07