LINQ to Entities查询错误

时间:2012-12-10 20:29:27

标签: c# asp.net-mvc linq entity-framework linq-to-entities

我遇到了一个我不熟悉的错误。我试图谷歌没有成功。 我写了以下查询,我遇到了这个错误。

无法在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; }
}

知道出了什么问题吗?

4 个答案:

答案 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