entity framework – 无效的列名“* _ID”

我已经缩小到Code First和Database首先EF之间的一些问题,但我不知道如何解决这个问题。 我会努力尽可能清楚,但我真的很想念自己在这里的一些理解。 这是entity framework4.4

我inheritance了一个使用entity framework的项目,但许多实际的文件被删除,没有真正的回头路。 我重新添加了EF(数据库优先),并复制了项目build立的T4设置。 它生成所有数据库模型和DBContext代码文件的代码版本。

如果我的连接string看起来像一个“正常的”.NET连接string,我得到关于一个无效的列错误名称“ProcessState_ID”不存在。 ProcessState_ID根本不在代码库中,它不在EDMX文件或任何东西中。 这似乎是查询中的一些自动EF转换。

当我使连接string匹配的entity framework模型,它工作正常。

现在试图匹配前面的代码与entity framework,我想保持“正常的”.NET连接string。

所以我有两个问题在这里:1.什么是从正常连接string到代码中的EF连接string的好方法? 2.是否有另一个修复,我没有看到停止无效的列名称错误?

检查是否有任何ICollections。

我所知道的是,当你有一个引用一个表的ICollection,并且没有可以找出的列时,它会创build一个让你试图build立表之间的连接。 这是ICollection发生的具体情况,并促使我“蠢货”试图弄清楚。

圣牛 – 经过几个小时的努力,我终于明白了这一点。

我正在做EF6数据库,我想知道“范围未知的列”错误 – 这是由于某种原因生成表名下划线列名,并试图find一个不存在的列。

在我的情况下,我的表中有一个表有两个外键引用到另一个表中相同的主键 – 如下所示:

 Animals Owners ======= ====== AnimalID (PK) Pet1ID <- FK to AnimalID Pet2ID <- also FK to AnimalID 

EF正在生成一些怪异的名字,比如Owners_AnimalID1Owners_AnimalID2 ,然后自行破解。

这里的诀窍是这些混淆的外键需要使用Fluent API在EF注册!

在主数据库上下文中,重写OnModelCreating方法并更改实体configuration。 最好,你将有一个单独的文件扩展了EntityConfiguration类,但你可以内联。

任何你这样做的方式,你需要添加这样的东西:

 public class OwnerConfiguration : EntityTypeConfiguration<Owner> { public OwnerConfiguration() { HasRequired(x => x.Animals) .WithMany(x => x.Owners) // Or, just .WithMany() .HasForeignKey(x => x.Pet1ID); } } 

而且,EF将(也许)开始按照您的预期工作。 繁荣。

另外,如果使用上面的空列.HasOptional() nullable column .HasOptional().HasRequired()出现相同的错误 – 只需使用.HasOptional()而不是.HasRequired()


这是让我越过驼峰的链接:

https://social.msdn.microsoft.com/Forums/en-US/862abdae-b63f-45f5-8a6c-0bdd6eeabfdb/getting-sqlexception-invalid-column-name-userid-from-ef4-codeonly?forum=adonetefx

然后,Fluent API文档帮助,特别是外键示例:

http://msdn.microsoft.com/en-us/data/jj591620.aspx

您也可以将configuration放在密钥的另一端,如下所述:

http://www.entityframeworktutorial.net/code-first/configure-one-to-many-relationship-in-code-first.aspx

现在我遇到了一些新的问题,但那是缺less的巨大的概念上的差距。 希望能帮助到你!

对于那些没有立即理解其他2个答案的人(比如我)来说,这是一个晚点。

所以…

EF正尝试映射到PARENT TABLES KEY-REFERENCE的EXPECTED名称…因为… FOREIGN KEY名称在数据库CHILD TABLE关系中被“更改或缩短”…您将获得上面的消息。

(这个修复可能在EF版本中有所不同)

对我来说修正是:
将“ForeignKey”属性添加到模型中

 public partial class Tour { public Guid Id { get; set; } public Guid CategoryId { get; set; } [Required] [StringLength(200)] public string Name { get; set; } [StringLength(500)] public string Description { get; set; } [StringLength(50)] public string ShortName { get; set; } [StringLength(500)] public string TourUrl { get; set; } [StringLength(500)] public string ThumbnailUrl { get; set; } public bool IsActive { get; set; } [Required] [StringLength(720)] public string UpdatedBy { get; set; } [ForeignKey("CategoryId")] public virtual TourCategory TourCategory { get; set; } } 

在我的情况下,我错误地定义了一个由两个外键组成的主键:

 HasKey(x => x.FooId); HasKey(x => x.BarId); HasRequired(x => x.Foo) .WithMany(y => y.Foos); HasRequired(x => x.Bar); 

我得到的错误是“无效的列名称Bar_ID”。

指定复合主键正确解决了这个问题:

 HasKey(x => new { x.FooId, x.BarId }); ... 

我也有这个问题,似乎有几个不同的原因。 对我来说,有一个id属性被错误地定义为int,而不是包含导航对象的父类中的long。 数据库中的id字段被定义为bigint,它对应于C#中的long。 这不会导致编译时错误,但会导致OP得到相同的运行时错误:

 // Domain model parent object public class WidgetConfig { public WidgetConfig(long id, int stateId, long? widgetId) { Id = id; StateId = stateId; WidgetId = widgetId; } private WidgetConfig() { } public long Id { get; set; } public int StateId { get; set; } // Ensure this type is correct public long? WidgetId { get; set; } public virtual Widget Widget { get; set; } } // Domain model object public class Widget { public Widget(long id, string name, string description) { Id = id; Name = name; Description = description; } private Widget() { } public long Id { get; set; } public string Name { get; set; } public string Description { get; set; } } // EF mapping public class WidgetConfigMap : EntityTypeConfiguration<WidgetConfig> { public WidgetConfigMap() { HasKey(x => x.Id); ToTable(nameof(WidgetConfig)); Property(x => x.Id).HasColumnName(nameof(WidgetConfig.Id)).HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity).IsRequired(); Property(x => x.StateId).HasColumnName(nameof(WidgetConfig.StateId)); Property(x => x.WidgetId).HasColumnName(nameof(WidgetConfig.WidgetId)); } } // Service public class WidgetsService : ServiceBase, IWidgetsService { private IWidgetsRepository _repository; public WidgetsService(IWidgetsRepository repository) { _repository = repository; } public List<WidgetConfig> ListWithDetails() { var list = _repository.ListWithDetails(); return new WidgetConfigMapping().ConvertModelListToDtoList(list).ToList(); } } // Repository public class WidgetsRepository: BaseRepository<WidgetConfig, long>, IWidgetsRepository { public WidgetsRepository(Context context) : base(context, id => widget => widget.Id == id) { } public IEnumerable<WidgetConfig> ListWithDetails() { var widgets = Query .Include(x => x.State) .Include(x => x.Widget); return widgets; } } 

对我来说,问题是我有两次在我的应用程序中映射表 – 一次通过Code First,一次通过Database First。

删除任何一个解决了我的情况下的问题。

假设:

  • Table
  • OtherTable
  • OtherTable_ID

select这种方法之一:

A)删除ICollection<Table>

如果您在检索Table时遇到与OtherTable_ID相关的错误,请转至您的OtherTable模型,并确保您没有ICollection<Table> 。 如果没有定义关系,框架会自动假定您必须具有FK到OtherTable,并在生成的SQL中创build这些额外的属性。

这个答案的所有信用属于@LUKE。 上面的答案是他在@drewid答案下的评论。 我觉得他的评论太干净了,于是我把它改写为答案。


B)

  • OtherTableId添加到Table

  • 在数据库表中定义OtherTableId

如果您有多次对同一个表的外键引用,那么您可以使用InverseProperty

像这样的东西 –

 [InverseProperty("MyID1")] public virtual ICollection<MyTable> set1 { get; set; } [InverseProperty("MyID2")] public virtual ICollection<MyTable> set2 { get; set; } 

对我来说(使用Visual Studio 2017和entity framework6.1.3下的数据库优先模型),重新启动Visual Studio和重build后,问题就消失了。