实体框架 - 流畅的 API - 创建奇怪的列 PK : FK FK.



我的项目是数据库优先,我使用的是实体框架 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());
}

我已经从其他用户那里读了一些关于这个问题的信息,问题应该在(自动生成的(OnModelCreateating中。

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; }
}

这一行看起来很可疑:

areas.Add(db.Area.Where(item => item.ID == link.areaID).First());

item.ID 是链接表记录的索引,而不是区域记录。

areas.Add(db.Area.Where(item => item.AreaID == link.areaID).First());

您上次运行数据库迁移是什么时候? 如果您的模型正确,并且您的数据库显示缺少字段,则数据库与代码不匹配。

我不太清楚你的目标,但你可以按如下方式重构你的代码:

此代码:

// 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);
}
}

在这里,您可以先了解有关实体框架代码的更多信息,请点击此链接

最新更新