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_AnimalID1
和Owners_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()
。
这是让我越过驼峰的链接:
然后,Fluent API文档帮助,特别是外键示例:
http://msdn.microsoft.com/en-us/data/jj591620.aspx
您也可以将configuration放在密钥的另一端,如下所述:
现在我遇到了一些新的问题,但那是缺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后,问题就消失了。
- EF Code First:如何从nuget包控制台中看到“EntityValidationErrors”属性?
- 使用MySqlentity framework4和Code-First Development CTP
- 什么是entity frameworkstream利的API?
- entity framework/ Linq EXpression从string转换为int
- EF包括其他实体(通用存储库模式)
- 插入到表中时发生错误,而不是从实体数据框架中触发
- ADO.Net EF – 如何在模型第一种方法中定义外键关系?
- 为什么我得到这个错误:没有为以下EntitySet / AssociationSet – Entity1指定的映射?
- 如何快速在我的EDMX模型中find特定的表格?