C# 无法在实体框架中获取导航属性
我正在Visual Studio 2015中构建一个WPF MVVM Light应用程序,使用Entity Framework 6连接到SQL Server 2008 R2数据库。需要搜索的两个表是:PersonnelTech及其子表PersonnelTechCostCenter PersonnelTech可以有任意数量的PersonnelTech成本中心记录,因此PersonnelTech ID是子表中的外键 这是父表:C# 无法在实体框架中获取导航属性,c#,wpf,entity-framework,linq,mvvm,C#,Wpf,Entity Framework,Linq,Mvvm,我正在Visual Studio 2015中构建一个WPF MVVM Light应用程序,使用Entity Framework 6连接到SQL Server 2008 R2数据库。需要搜索的两个表是:PersonnelTech及其子表PersonnelTechCostCenter PersonnelTech可以有任意数量的PersonnelTech成本中心记录,因此PersonnelTech ID是子表中的外键 这是父表: CREATE TABLE [dbo].[PersonnelTech] (
CREATE TABLE [dbo].[PersonnelTech]
(
[personnelTechId] [int] IDENTITY(1,1) NOT NULL,
[name] [nvarchar](95) NOT NULL,
[email] [nvarchar](95) NOT NULL,
[isActive] [bit] NOT NULL
CONSTRAINT [DF_PersonnelTech_isActive] DEFAULT ((1)),
[createdDate] [datetime] NOT NULL CONSTRAINT [DF_PersonnelTech_createdDate] DEFAULT (getdate()),
CONSTRAINT [PK_PersonnelTech]
PRIMARY KEY CLUSTERED ([personnelTechId] ASC)
WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF,
IGNORE_DUP_KEY = OFF,
ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON)
)
这是孩子:
CREATE TABLE [dbo].[PersonnelTechCostCenter]
(
[personnelTechCostCenterId] [int] IDENTITY(1,1) NOT NULL,
[personnelTechId] [int] NOT NULL,
[costCenter] [nvarchar](50) NOT NULL,
[organizationalUnit] [nvarchar](50) NULL,
[isActive] [bit] NOT NULL
CONSTRAINT [DF_PersonnelTechCostCenter_isActive] DEFAULT ((1)),
[createdDate] [datetime] NOT NULL
CONSTRAINT [DF_PersonnelTechCostCenter_createdDate] DEFAULT (getdate()),
CONSTRAINT [PK_PersonnelTechCostCenter]
PRIMARY KEY CLUSTERED ([personnelTechCostCenterId] ASC)
WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF,
IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON,
ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
ALTER TABLE [dbo].[PersonnelTechCostCenter] WITH CHECK
ADD CONSTRAINT [FK_PersonnelTechCostCenter_PersonnelTech]
FOREIGN KEY([personnelTechId])
REFERENCES [dbo].[PersonnelTech] ([personnelTechId])
ALTER TABLE [dbo].[PersonnelTechCostCenter]
CHECK CONSTRAINT [FK_PersonnelTechCostCenter_PersonnelTech]
在我的方法中,我尝试使用LINQ获取父记录和子记录,并用它们填充一些ObservableCollection视图模型:
using (var db = new MyEntities())
{
var query = (from pt in db.PersonnelTeches
where pt.isActive.Equals(true)
orderby pt.name
select new PersonnelTechViewModel
{
PersonnelTechId = pt.personnelTechId,
Name = pt.name,
Email = pt.name,
IsActive = pt.isActive,
CreatedDate = pt.createdDate,
CostCenterVms = new ObservableCollection<PersonnelTechCostCenterViewModel>(pt.PersonnelTechCostCenters.Where(x => x.isActive)
.Select(
ptcc => new PersonnelTechCostCenterViewModel
{
PersonnelTechCostCenterId = ptcc.personnelTechCostCenterId,
PersonnelTechId = ptcc.personnelTechId,
CostCenter = ptcc.costCenter,
OrganizationalUnit = ptcc.organizationalUnit,
IsActive = ptcc.isActive,
CreatedDate = ptcc.createdDate
}).OrderBy(x => x.CostCenter).DefaultIfEmpty())
}).ToList();
return await Task.Run(() => new ObservableCollection<PersonnelTechViewModel>(query));
}
然而,这在返回声明中被放大,并表示:
LINQ to实体中只支持无参数构造函数和初始值设定项
其他帖子说你需要把第一部分变成它自己的部分;最后,您需要执行另一个操作。选择以从导航属性填充。我不知道如何做到这一点。好的,首先我不知道你为什么要做一个选择,似乎要从技术人员到他们的中心。EF应该通过其上下文操作为您执行所有连接。让我们把它变得更简单,比如说 我有一个表tePerson,其中包含字段:PersonId、FirstName、LastName、OrderId。 此表包含值
1 Brett X 1
2 Emily X 2
4 Ryan Y 1
10 Mark Z 1
OrderId是表的外键,该表只有两个字段:OrderId和Description
1 Shirt
2 Dress
设置实体框架时,您需要设置存在的上下文,然后将对象从生成的POCO对象的T4模板实现为可用的形式。通常,您会在名为“MyEntities.edmx”的类下面看到上下文“MyEntities.context.tt”和“MyEntities.tt”。实体上下文通常包含对所有POCO对象的引用,而在另一个上下文下,您的POCO被创建为与数据库中的内容类似的.NET匹配项。但是,如果您有一个外键,您应该让实体创建一个关系并为您进行连接。因此,在我为tePerson教授的Poco课程中,我看到:
public partial class tePerson
{
public int PersonId { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public Nullable<int> OrderId { get; set; }
public virtual teOrder teOrder { get; set; }
}
我只是用“ToList”实现了一个对象,然后我用lambda“select”遍历了一个结构,通过外键得到了它的子对象和它们的子对象,然后用“ToList”实现了这个结构
public partial class teOrder
{
public teOrder()
{
this.tePersons = new HashSet<tePerson>();
}
public int OrderId { get; set; }
public string Description { get; set; }
public virtual ICollection<tePerson> tePersons { get; set; }
}
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using System.Timers;
using System.Data;
using System.Linq;
using System.Collections.ObjectMode;
static void Main(string[] args)
{
using (var context = new TesterEntities())
{
var peopleWithOrderOfOne = context.tePersons.Where(x => x.OrderId == 1);
// Go down to get the orders for Brett, Ryan, and Mark. I am realizing an object that is a foreign key merely by selecting the complex object.
// In this case x.teOrder is a POCO class mapped to another POCO class
var observable = new ObservableCollection<teOrder>(peopleWithOrderOfOne.ToList().Select(x => x.teOrder).ToList());
// display it
observable.ToList().ForEach(x => Console.WriteLine($"{x.Description}"));
//If you want to fully realize new objects you need to make them concrete by doing a select followed by a toList to materialize them, else they are not realized yet.
// THis WILL NOT WORK:
//var madeupPeopleAndOrders = context.tePersons
// .Select(x =>
// new tePerson
// {
// FirstName = x.FirstName,
// LastName = x.LastName,
// teOrder = new teOrder
// {
// OrderId = x.OrderId.Value,
// Description = x.teOrder.Description
// }
// });
// THis WILL WORK:
var madeupPeopleAndOrders = context.tePersons
.ToList()
.Select(x =>
new tePerson
{
FirstName = x.FirstName,
LastName = x.LastName,
teOrder = new teOrder
{
OrderId = x.OrderId.Value,
Description = x.teOrder.Description
}
});
madeupPeopleAndOrders.ToList().ForEach(x => Console.WriteLine($"{x.FirstName} {x.LastName} {x.teOrder.Description}"));
}
Console.ReadLine();
}
context.tableName.toList().Select(x => x.childobject.itschildobject.value).ToList()