EF Code First:添加外键关系Linq-to-Entity投影
EF Code First: Add a Foreign Key relationship Linq-to-Entity projection
我在使用 entity framework 从代码创建数据库外键方面遇到了问题。下面显示的 tables 被查询,数据被投影到另一个模型中,如下所示。一切似乎都是正确的,尽管当我查询数据时,通过 AddressId 连接的列似乎没有工作并且我的 "Street" 列 returns 空白数据。
namespace Mvc4Connect.ViewModels
{
[Table("PersonEntity")]
public class PersonEntity : EntityTypeConfiguration<PersonEntity>
{
//Constructor
public PersonEntity()
{
this.ToTable("TB008555", schemaName: "SchemaUser");
this.Property(c => c.PersonId).HasColumnName("CL005500");
this.Property(c => c.FirstName).HasColumnName("CL005545");
this.Property(c => c.LastName).HasColumnName("CL005550");
this.Property(c => c.AddressId).HasColumnName("CL044760");
}
[Key]
[DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
public int PersonId { get; set; }
public String FirstName { get; set; } //firstname
public String LastName { get; set; } //lastname
[ForeignKey("AddressEntity")]
public int AddressId { get; set; }
public virtual ICollection<AddressEntity> AddressEntity { get; set; }
}
}
我的第二个 table 包含加入的 AddressId
namespace Mvc4Connect.ViewModels
{
[Table("AddressEntity")]
public class AddressEntity : EntityTypeConfiguration<AddressEntity>
{
//Constructor
public AddressEntity()
{
this.ToTable("TB047697", schemaName: "SchemaUser");
this.Property(c => c.AddressId).HasColumnName("CL045695");
this.Property(c => c.Street).HasColumnName("CL042710");
this.Property(c => c.City).HasColumnName("CL044747");
this.Property(c => c.State).HasColumnName("CL047460");
}
[Key]
[DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
public int AddressId { get; set; }
public string Street { get; set; }
public string City { get; set; }
public string State { get; set; }
}
}
我的实体上下文
public class EntityContext : DbContext
{
public DbSet<PersonEntity> Persons { get; set; }
public DbSet<AddressEntity> Address { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Configurations.Add(new PersonEntity());
modelBuilder.Configurations.Add(new AddressEntity());
}
}
这是我试图在我的 API 控制器中使用的查询。
var dbv = new EntityContext();
var query = (from vt in dbv.Persons
from ad in dbv.Address
where vt.LastName.StartsWith(ln)
where vt.FirstName.StartsWith(fn)
where ad.AddressId == vt.AddressId
select new PersonVM() // Create new object for projection
{
PersonId = vt.PersonId,
FirstName = vt.FirstName,
LastName = vt.LastName,
Street = ad.Street, // Blank Street data
AddressId = vt.AddressId // Debug to assure Id is assigned
});
return query.ToList();
我认为您在确定表之间的关系时犯了错误:组合:
public class PersonEntity : EntityTypeConfiguration<PersonEntity>
{
[ForeignKey("AddressEntity")]
public int AddressId { get; set; }
public virtual ICollection<AddressEntity> AddressEntity { get; set; }
//other properties...
}
不正确!相反,如果 Person 和 Address 之间的关系是一对多的,你应该这样写:
public class PersonEntity : EntityTypeConfiguration<PersonEntity>
{
//[ForeignKey("AddressEntity")]
//public int AddressId { get; set; }
public virtual ICollection<AddressEntity> AddressEntity { get; set; }
//other properties...
}
和
public class AddressEntity : EntityTypeConfiguration<AddressEntity>
{
[ForeignKey("Person")]
public int PersonId { get; set; }
public virtual PersonEntity Person { get; set; }
//other properties...
}
最终查询将如下所示:
var query = (from vt in dbv.Persons
from ad in dbv.Address
where vt.LastName.StartsWith(ln)
where vt.FirstName.StartsWith(fn)
where vt.PersonId == ad.PersonId//this line was changed!
select new PersonVM
{
vt.PersonId,
vt.FirstName,
vt.LastName,
ad.Street,
ad.AddressId //this line was changed!
});
此查询将 return 不是人,而是包含关于人的信息的地址。如果你想把人带上他们的地址,你应该执行 group by 操作,同时左外连接来保存没有地址的人:
var query = (from vt in dbv.Persons
where vt.LastName.StartsWith(ln)
where vt.FirstName.StartsWith(fn)
join ad in dbv.Address on vt.PersonId equals ad.PersonId into subAddresses
from subAdr in subAddresses.DefaultIfEmpty()
group subAdr by new { vt.PersonId, vt.FirstName, vt.LastName } into groupPers
select new
{
groupPers.Key.PersonId,
groupPers.Key.FirstName,
groupPers.Key.LastName,
addresses = groupPers
});
我在使用 entity framework 从代码创建数据库外键方面遇到了问题。下面显示的 tables 被查询,数据被投影到另一个模型中,如下所示。一切似乎都是正确的,尽管当我查询数据时,通过 AddressId 连接的列似乎没有工作并且我的 "Street" 列 returns 空白数据。
namespace Mvc4Connect.ViewModels
{
[Table("PersonEntity")]
public class PersonEntity : EntityTypeConfiguration<PersonEntity>
{
//Constructor
public PersonEntity()
{
this.ToTable("TB008555", schemaName: "SchemaUser");
this.Property(c => c.PersonId).HasColumnName("CL005500");
this.Property(c => c.FirstName).HasColumnName("CL005545");
this.Property(c => c.LastName).HasColumnName("CL005550");
this.Property(c => c.AddressId).HasColumnName("CL044760");
}
[Key]
[DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
public int PersonId { get; set; }
public String FirstName { get; set; } //firstname
public String LastName { get; set; } //lastname
[ForeignKey("AddressEntity")]
public int AddressId { get; set; }
public virtual ICollection<AddressEntity> AddressEntity { get; set; }
}
}
我的第二个 table 包含加入的 AddressId
namespace Mvc4Connect.ViewModels
{
[Table("AddressEntity")]
public class AddressEntity : EntityTypeConfiguration<AddressEntity>
{
//Constructor
public AddressEntity()
{
this.ToTable("TB047697", schemaName: "SchemaUser");
this.Property(c => c.AddressId).HasColumnName("CL045695");
this.Property(c => c.Street).HasColumnName("CL042710");
this.Property(c => c.City).HasColumnName("CL044747");
this.Property(c => c.State).HasColumnName("CL047460");
}
[Key]
[DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
public int AddressId { get; set; }
public string Street { get; set; }
public string City { get; set; }
public string State { get; set; }
}
}
我的实体上下文
public class EntityContext : DbContext
{
public DbSet<PersonEntity> Persons { get; set; }
public DbSet<AddressEntity> Address { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Configurations.Add(new PersonEntity());
modelBuilder.Configurations.Add(new AddressEntity());
}
}
这是我试图在我的 API 控制器中使用的查询。
var dbv = new EntityContext();
var query = (from vt in dbv.Persons
from ad in dbv.Address
where vt.LastName.StartsWith(ln)
where vt.FirstName.StartsWith(fn)
where ad.AddressId == vt.AddressId
select new PersonVM() // Create new object for projection
{
PersonId = vt.PersonId,
FirstName = vt.FirstName,
LastName = vt.LastName,
Street = ad.Street, // Blank Street data
AddressId = vt.AddressId // Debug to assure Id is assigned
});
return query.ToList();
我认为您在确定表之间的关系时犯了错误:组合:
public class PersonEntity : EntityTypeConfiguration<PersonEntity>
{
[ForeignKey("AddressEntity")]
public int AddressId { get; set; }
public virtual ICollection<AddressEntity> AddressEntity { get; set; }
//other properties...
}
不正确!相反,如果 Person 和 Address 之间的关系是一对多的,你应该这样写:
public class PersonEntity : EntityTypeConfiguration<PersonEntity>
{
//[ForeignKey("AddressEntity")]
//public int AddressId { get; set; }
public virtual ICollection<AddressEntity> AddressEntity { get; set; }
//other properties...
}
和
public class AddressEntity : EntityTypeConfiguration<AddressEntity>
{
[ForeignKey("Person")]
public int PersonId { get; set; }
public virtual PersonEntity Person { get; set; }
//other properties...
}
最终查询将如下所示:
var query = (from vt in dbv.Persons
from ad in dbv.Address
where vt.LastName.StartsWith(ln)
where vt.FirstName.StartsWith(fn)
where vt.PersonId == ad.PersonId//this line was changed!
select new PersonVM
{
vt.PersonId,
vt.FirstName,
vt.LastName,
ad.Street,
ad.AddressId //this line was changed!
});
此查询将 return 不是人,而是包含关于人的信息的地址。如果你想把人带上他们的地址,你应该执行 group by 操作,同时左外连接来保存没有地址的人:
var query = (from vt in dbv.Persons
where vt.LastName.StartsWith(ln)
where vt.FirstName.StartsWith(fn)
join ad in dbv.Address on vt.PersonId equals ad.PersonId into subAddresses
from subAdr in subAddresses.DefaultIfEmpty()
group subAdr by new { vt.PersonId, vt.FirstName, vt.LastName } into groupPers
select new
{
groupPers.Key.PersonId,
groupPers.Key.FirstName,
groupPers.Key.LastName,
addresses = groupPers
});