我遇到了一个我不熟悉的错误。我试图谷歌没有成功。 我写了以下查询,我遇到了这个错误。
无法在LINQ to Entities查询中构造实体或复杂类型“MyWebProject.Models.UserDetail”。
查询:
UsersContext db = new UsersContext();
var userdata = (from k in db.UserDetails
where k.UserId == WebSecurity.CurrentUserId
select new UserDetail()
{
FullName = k.FullName,
Email = k.Email,
About = k.About,
Link = k.Link,
UserSchool = new School()
{
SchoolId = k.UserSchool.SchoolId,
SchoolName = k.UserSchool.SchoolName
},
UserCourse = new Course()
{
CourseId=k.UserCourse.CourseId,
CourseName=k.UserCourse.CourseName
},
Country=k.Country
}).FirstOrDefault();
类别:
public class UserDetail
{
public int Id { get; set; }
public int UserId { get; set; }
public string FullName { get; set; }
public string Link { get; set; }
public bool? Verified { get; set; }
public string Email { get; set; }
public string About { get; set; }
public School UserSchool { get; set; }
public Course UserCourse { get; set; }
public string Country { get; set; }
}
public class School
{
public int SchoolId { get; set; }
public string SchoolName { get; set; }
public string Country { get; set; }
}
public class Course
{
public int CourseId { get; set; }
public string CourseName { get; set; }
public School School { get; set; }
}
知道出了什么问题吗?
答案 0 :(得分:4)
看起来这是由于您在查询中间创建复杂属性School和Course的方式。最好选择User(删除选择转换),然后使用导航属性访问这些对象,而不是手动构建它们。只要您使用外键建立了正确的关系,导航就是为此而设的。
UsersContext db = new UsersContext();
var userdata = (from k in db.UserDetails
where k.UserId == WebSecurity.CurrentUserId})
.FirstOrDefault();
// access navigation properties which will perform the joins on your behalf
// this also provides for lazy loading which would make it more effecient. (it wont load the school object until you need to access it)
userdata.School
userdata.Course
关于导航属性的MSDN文章:http://msdn.microsoft.com/en-us/library/vstudio/bb738520(v=vs.100).aspx
答案 1 :(得分:3)
这应该可以满足您的需求。它会将您的对象作为查询的一部分加载(而不是依赖于延迟加载)。
UsersContext db = new UsersContext();
var userdata = db.UserDetails.Include(x => x.UserSchool)
.Include(x => x.UserCourse)
.Include(x => x.Country)
.Where(x => x.UserId == WebSecurity.CurrentUserId)
.FirstOrDefault();
答案 2 :(得分:0)
我认为这是因为您的实体与您尝试创建的对象具有相同的名称。尝试重命名要返回的对象。如果要返回与实体相同的类型,请尝试使用.Include(“relationshipname”)功能进行预先加载。
答案 3 :(得分:0)
@Yakimych的答案如下。
您不能(也不应该)投影到映射的实体。但是,您可以投射到匿名类型或DTO上:
public class ProductDTO
{
public string Name { get; set; }
// Other field you may need from the Product entity
}
您的方法将返回DTO列表。
public List<ProductDTO> GetProducts(int categoryID)
{
return (from p in db.Products
where p.CategoryID == categoryID
select new ProductDTO { Name = p.Name }).ToList();
}
EF中的映射实体基本上代表数据库表。如果您投影到映射的实体,您基本上做的是部分加载一个实体,这不是一个有效的状态。 EF将不会有任何线索如何例如在将来处理这样一个实体的更新(默认行为可能是用空值或对象中的任何内容覆盖未加载的字段)。这将是一个危险的操作,因为您可能会丢失数据库中的某些数据,因此不允许在EF中部分加载实体(或投影到映射的实体)。
有关详细信息,请访问以下链接: The entity cannot be constructed in a LINQ to Entities query