我的项目是数据库优先,并且我正在使用Entity Framework 6.2.0。
所以我有以下简单的例子:
Person [1] [n] Link_Table [n] [1] Area
====== ========== ====
ID ID ID
PersonID (FK)
AreaID (FK)
现在,当使用以下代码时,它会通过内部异常“无效的列名'Area2_ID'”。
Db_Context db = new Db_Context();
// getting all links with specific "personID"
List<Link_Table> links = db.Link_Table.Where(item => item.PersonID == personID).ToList();
// now getting all areas
List<Area> areas= new List<Area>();
foreach (Link_Table link in links)
{
// ERROR
areas.Add(db.Area.Where(item => item.ID == link.areaID).First());
}
我已经阅读了其他用户关于此问题的一些文章,该问题应该在(自动生成的) OnModelCreating 中。
modelBuilder.Entity<Area>()
.Property(e => e.Description)
.IsUnicode(false);
modelBuilder.Entity<Area>()
.HasOptional(e => e.Area1)
.WithRequired(e => e.Area2);
无论出于何种原因在代码中使用EF并创建一个新的Area-Object,它不仅会显示“ ID”-属性,还会显示“ Area1”-和“ Area2”-属性。
问题 我该如何处理?列“ Area1_ID”和“ Area2_ID”仅存在于EF中,不存在于数据库中。我可以删除这些属性或其他方法来防止出现异常吗?
编辑: 我的模特:
[Table("Area")]
public partial class Area
{
public Guid ID { get; set; }
[StringLength(40)]
public string Name { get; set; }
[Column(TypeName = "text")]
public string Description{ get; set; }
public virtual Area Area1 { get; set; }
public virtual Area Area2 { get; set; }
}
public partial class Link_Table
{
public Guid ID { get; set; }
public Guid? Person_ID { get; set; }
public Guid? Area_ID { get; set; }
public virtual Person Person{ get; set; }
}
[Table("Person")]
public partial class Person
{
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")]
public Person()
{
Link_Table = new HashSet<Link_Table>();
}
public Guid ID { get; set; }
}
答案 0 :(得分:0)
这行看起来很可疑:
areas.Add(db.Area.Where(item => item.ID == link.areaID).First());
item.ID是链接表记录的索引,而不是区域记录。
areas.Add(db.Area.Where(item => item.AreaID == link.areaID).First());
答案 1 :(得分:0)
对我来说,您的目标不是很清楚,但是您可以按照以下方式重构代码:
此代码:
// now getting all areas
List<Area> areas= new List<Area>();
foreach (Link_Table link in links)
{
// ERROR
areas.Add(db.Area.Where(item => item.ID == link.areaID).First());
}
可以替换为:
var areas=links.Select(link => link.Area).ToList() // if you decide to add a navigation property
或
var areas=db.Areas.Where(area => links?.Any(link=>link.areaID==area.Id)).ToList();
您可能从.First()
得到的错误很可能是将来用于.FirstOrDefault()
请参见下面的代码优先实现示例:
class Program
{
static void Main(string[] args)
{
var db = new ApplicationDbContext();
var person = new Person();
IQueryable<Link> personLinks = db.Links.Where(x => x.PersonId == person.Id);
List<Area> personAreas = personLinks.GroupBy(x => x.Area).Select(x => x.Key).ToList();
}
}
public class Person
{
public int Id { get; set; }
public ICollection<Link> Links { get; set; }
}
public class Link
{
public int Id { get; set; }
public int PersonId { get; set; }
public Person Person { get; set; }
public int AreaId { get; set; }
public Area Area { get; set; }
}
public class Area
{
public int Id { get; set; }
public ICollection<Link> Links { get; set; }
}
public class ApplicationDbContext : DbContext
{
public DbSet<Person> Persons { get; set; }
public DbSet<Area> Areas { get; set; }
public DbSet<Link> Links { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<Link>()
.HasRequired(x => x.Person)
.WithMany(x => x.Links)
.HasForeignKey(x => x.PersonId)
.WillCascadeOnDelete(true);
modelBuilder.Entity<Link>()
.HasRequired(x => x.Area)
.WithMany(x => x.Links)
.HasForeignKey(x => x.AreaId)
.WillCascadeOnDelete(false);
base.OnModelCreating(modelBuilder);
}
}
在这里您可以首先了解有关实体框架代码的更多信息follow this link
答案 2 :(得分:0)
您上次运行数据库迁移的时间是什么时候?如果您的模型是正确的,并且您的数据库说缺少字段,那么该数据库与代码不匹配。