2012-12-10 2 views
2

나는 familier가 아닌 오류가 발생했습니다. 나는 성공하지 못한 채 구글을 시도했다. 이 오류가 발생하는 곳에서 다음 쿼리를 작성했습니다.LINQ to Entities 쿼리 오류

엔터티 또는 복합 유형 'MyWebProject.Models.UserDetail'은 LINQ to Entities 쿼리에서 구성 할 수 없습니다.

쿼리 :

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

쿼리 도중에 복잡한 속성 인 School and Course를 만드는 방법 때문인 것으로 보입니다. 사용자 (선택 변환 제거)를 선택한 다음 탐색 특성을 사용하여 수동으로 작성하는 대신 해당 오브젝트에 액세스하는 것이 더 좋을 것입니다. 내비게이션은 외래 키로 작성된 적절한 관계가있는 한이 용도로 사용됩니다. 탐색 속성에 대한

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

+0

이 있는지 확인 @kandroid => m.UserSchool.SchoolName) '을 선택하십시오. 나는 학교 이름을 얻지 않는다. – kandroid

+0

UserDetail 개체에 적절한 SchoolID가 있는지 확인하여 학교 테이블에 연결할 수 있도록합니다. 그런 다음에 학교 테이블에 이름이 있습니까? 즉, 먼저 조인을 사용하여 원시 쿼리를 수행하면 예상 결과를 얻을 수 있습니다. 데이터가 올바른지 확인한 후 컨트롤러가보기를 렌더링하고 속성을 확인하기 전에 중단 점을 설정하십시오. – Despertar

+0

게으른로드를 사용하지 않는 경우 문제가 될 수 있습니다. 게으른 로딩에 의존하기보다 명시 적으로 객체를로드하는 방법을 보여주기 위해 아래에서 내 대답을 업데이트했습니다. –

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(); 
+0

내가 코드를 사용할 수없는 몇 가지 이유로 잘 모릅니다. 그것은 '람다 표현식을 대리자 유형이 아니므로'string '을 입력 할 수 없습니다.'오류가 발생합니다. ' 다른 실수는 있습니까? – kandroid

+0

@kandroid 'using System'을 추가하십시오.Linq;'클래스 –

+0

에 이미 있습니다. :) 내가 'select * from userdetails inner'와 같은 데이터베이스에 쿼리를 작성하면 Schools on UserDetails.UserSchool_SchoolId = Schools.SchoolId '로 예상되는 결과를 얻습니다. 코드 첫 번째 모델에서 나는 아주 새로운 것이다. 공용 클래스 UsersContext : DbContext { 공공 UsersContext() : 내가 여기에 아무 것도 입력해야하나요 기본 ("DefaultConnection") { } 공공 DbSet UserProfiles을 {얻을; 세트; } public DbSet UserDetails {get; 세트; } } – kandroid

0

나는 당신의 엔티티가 생성하려는 객체의 이름이 같은 있기 때문에 생각합니다. 되돌리려는 개체의 이름을 변경하십시오. 엔티티와 동일한 유형을 반환하려면 .Include ("relationshipname") 기능을 사용하여 열망하는로드를 시도하십시오.

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는 예를 들어 미래 엔 엔티티의 업데이트를 처리해야합니다 (기본 동작은 null이 아닌로드 된 필드를 덮어 쓰거나 객체에있는 모든 것을 덮어 쓰는 것입니다). DB에서 일부 데이터가 손실 될 위험이 있으므로 위험한 작업이므로 EF에서 엔티티 (또는 매핑 된 엔티티에 프로젝트)를 부분적으로로드 할 수 없습니다. 자세한 내용은

는 아래의 링크로 이동하십시오 : The entity cannot be constructed in a LINQ to Entities query