복붙노트

[SQL] 하나의 필드없이 entityframework에서 개체를 검색

SQL

하나의 필드없이 entityframework에서 개체를 검색

나는 데이터베이스와 연결하는 엔티티 프레임 워크를 사용하고 있습니다. 나는 하나의 작은 문제를했습니다 :

나는 (FILESTREAM 포함) 한 VARBINARY (MAX) 열이 하나 개의 테이블을했습니다.

나는 나머지 (파일의 메타 데이터)은 "데이터"부분을 관리하기 위해 SQL 요청을 사용하지만, EF하고 있습니다.

나는 ... 파일의 모든 파일의 아이디, 이름, GUID, 수정 날짜를 얻을 수있다 하나 개의 코드를했습니다. 이 모든 "데이터"필드에서 필요로하지 않는다.

이 열이없는 목록 만 작성을 검색 할 수있는 방법이 있습니까?

같은 뭔가

context.Files.Where(f=>f.xyz).Exclude(f=>f.Data).ToList();

??

나는 익명의 개체를 만들 수 있습니다 알지만, 방법에 그래서 아무 익명의 방법으로 결과를 전송해야합니다. 그리고 익명 형식의 목록에 넣고, 다음 내 비 익명 형식 (파일)의 목록을 작성하고 싶지 않아요.

목표는이를 방지하는 것입니다 :

using(RsSolutionsEntities context = new RsSolutionsEntities())
{
    var file = context.Files
        .Where(f => f.Id == idFile)
        .Select(f => new {
            f.Id, f.MimeType, f.Size, f.FileName, f.DataType,
            f.DateModification, f.FileId
        }).FirstOrDefault();

    return new File() {
        DataType = file.DataType, DateModification = file.DateModification,
        FileId = file.FileId, FileName = file.FileName, Id = file.Id,
        MimeType = file.MimeType, Size = file.Size
    };
}

(그렇지 않으면 당신은 NotSupportedException이를 얻을 수 있기 때문에 내가 여기에 익명 형식을 사용하고 있습니다 : 엔티티 또는 복합 형 'ProjectName.File이'엔티티 질의에 LINQ으로 구성 할 수 없습니다.)

(예를 들어,이 코드는 이전의 예외를 던져 :

File file2 = context.Files.Where(f => f.Id == idFile)
  .Select(f => new File() {Id = f.Id, DataType = f.DataType}).FirstOrDefault();

그리고 "파일은"나는 context.Files.ToList로 얻을 유형입니다 (). 이것은 좋은 클래스입니다 :

using File = MyProjectNamespace.Common.Data.DataModel.File;

파일 내 EF의 데이터 컨텍스트의 알려진 클래스입니다 :

public ObjectSet<File> Files
{
    get { return _files  ?? (_files = CreateObjectSet<File>("Files")); }
}
private ObjectSet<File> _files;

해결법

  1. ==============================

    1.회원님이 피하고 싶은 투사하지 않고. 열이 매핑되는 경우는 엔티티의 자연적인 부분이다. 이 항목이없는 실체가 완료되지 않은 -은 다른 데이터 세트 = 투영된다.

    회원님이 피하고 싶은 투사하지 않고. 열이 매핑되는 경우는 엔티티의 자연적인 부분이다. 이 항목이없는 실체가 완료되지 않은 -은 다른 데이터 세트 = 투영된다.

    예외는 당신이 매핑 된 엔티티 프로젝트 수 없다고한다. 프로젝션 서로 다른 데이터 세트를 만들고 EF는 "일부 단체"좋아하지 않는다 - 나는 위의 이유는 언급했다.

    그것은 디자이너에서 삭제 재산에 충분하지 않습니다. 당신은 (데이터베이스에서 각 업데이트가 열 등을 넣어 것)뿐만 아니라 당신의 모델이 매우 취약하게되는 SSDL에서 XML 및 삭제 열로 EDMX를 열어야합니다. 당신이 열을 매핑 할 수없는 경우에는 열없이 데이터베이스보기를 사용하는 대신 테이블의지도보기 그러나 당신은 데이터를 삽입 할 수 없습니다합니다.

    모든 문제에 대한 해결 방법으로 테이블 분할을 사용하고 1과 다른 엔티티에 문제가있는 이진 열을 분리 : 기본 파일 엔티티 1 개 관계를.

  2. ==============================

    2.나는 이런 식으로 뭔가를 할 거라고 :

    나는 이런 식으로 뭔가를 할 거라고 :

    var result = from thing in dbContext.Things
                 select new Thing {
                     PropertyA = thing.PropertyA,
                     Another = thing.Another
                     // and so on, skipping the VarBinary(MAX) property
                 };
    

    것은 당신의 실체가 어디 EF 구체화하는 방법을 알고있다. 이 조회에 필요하지 않은 이후 결과 SQL 문은 그 결과 세트의 큰 열을 포함하지 않아야합니다.

    편집 : 편집에서, 당신은 오류 NotSupportedException이 얻을 : 엔티티 또는 복합 형 'ProjectName.File은'엔티티 질의에 LINQ으로 구성 할 수 없습니다. 당신은 엔티티로 클래스를 매핑하지 않았기 때문에. 당신은 EF가 알아야하고 적절한 SQL 문을 생성하는 기대하지 않는 엔티티 쿼리에 대한 LINQ에서 개체를 포함 할 수 없습니다.

    당신은 제외합니다 VARBINARY (MAX)의 정의에 열 또는 위의 코드를 사용하는 것이 다른 유형을 매핑 할 수 있습니다.

  3. ==============================

    3.당신은이 작업을 수행 할 수 있습니다

    당신은이 작업을 수행 할 수 있습니다

    var files = dbContext.Database.SqlQuery<File>("select FileId, DataType, MimeType from Files");
    

    아니면 이거:

    var files = objectContext.ExecuteStoreQuery<File>("select FileId, DataType, MimeType from Files");
    

    EF의 버전에 따라

  4. ==============================

    4.내가 파일의 내용과 콘텐츠 필드가 문서의 개체 크기 즉, 일부 100MB의이 있기 때문에 나는이 요구 사항을했고, 나는 나머지 열을 반환하고 싶어하는 검색 기능을 가지고있다.

    내가 파일의 내용과 콘텐츠 필드가 문서의 개체 크기 즉, 일부 100MB의이 있기 때문에 나는이 요구 사항을했고, 나는 나머지 열을 반환하고 싶어하는 검색 기능을 가지고있다.

    내가 사용 투사로 선택했다 :

    IQueryable<Document> results = dbContext.Documents.Include(o => o.UploadedBy).Select(o => new {
        Content = (string)null,
        ContentType = o.ContentType,
        DocumentTypeId = o.DocumentTypeId,
        FileName = o.FileName,
        Id = o.Id,
        // etc. even with related entities here like:
        UploadedBy = o.UploadedBy
    });
    

    이어서 제 WebApi 제어기는 .Skip, .Take 및 .ToList 적용 공통 매김 기능이 결과 객체를 전달한다.

    쿼리가 실행됩니다 때 100MB의 데이터가 접촉되지 않는, 쿼리가 빨리 원하는 것 같다, 그래서 그것은, 내용 열을 액세스하지 않는이 수단 /가 될 것으로 기대합니다.

    이 힘은 당신이 구현해야 할 단계되지 않도록 다음, 나는,이 경우 거의 정확히 엔티티 클래스와 같은 내 DTO 클래스로 다시 캐스팅,하지만 그래서, 내 전형적인 WebApi 코딩 패턴을 따른다있다 :

    var dtos = paginated.Select(o => new DocumentDTO
    {
        Content = o.Content,
        ContentType = o.ContentType,
        DocumentTypeId = o.DocumentTypeId,
        FileName = o.FileName,
        Id = o.Id,
        UploadedBy = o.UploadedBy == null ? null : ModelFactory.Create(o.UploadedBy)
    });
    

    그럼 난 DTO의 목록을 반환 :

    return Ok(dtos);
    

    원래 포스터의 요구 사항에 적합하지 않을 수 있습니다 프로젝션을 사용하지만, 당신은 DTO 클래스를 사용하는 경우, 당신은 어쨌든 변환하고 그래서. 당신은 쉽게 실제 엔티티로를 반환하는 다음 작업을 수행 할 수 있습니다 :

    var dtos = paginated.Select(o => new Document
    {
        Content = o.Content,
        ContentType = o.ContentType,
        DocumentTypeId = o.DocumentTypeId,
        //...
    

    그냥 몇 푼의 순서에 따라하지만이 나를 위해 잘 노력하고 있습니다.

  5. ==============================

    5.EF 코어 2의 나는이 같은 솔루션을 구현 :

    EF 코어 2의 나는이 같은 솔루션을 구현 :

    var files = context.Files.AsNoTracking()
                             .IgnoreProperty(f => f.Report)
                             .ToList();
    

    기본 아이디어는 예를 들어이 쿼리에 대해 설정하는 것입니다 :

    SELECT [f].[Id], [f].[Report], [f].[CreationDate]
    FROM [File] AS [f]
    

    이 어 :

    SELECT [f].[Id], '' as [Report], [f].[CreationDate]
    FROM [File] AS [f]
    

    여기에 전체 소스 코드를 볼 수 있습니다 https://github.com/aspnet/EntityFrameworkCore/issues/1387#issuecomment-495630292

  6. ==============================

    6.

    var file = context.Files
            .Where(f => f.Id == idFile)
            .FirstOrDefault() // You need to exeucte the query if you want to reuse the type
            .Select(f => new {
                f.Id, f.MimeType, f.Size, f.FileName, f.DataType,
                f.DateModification, f.FileId
            }).FirstOrDefault();
    

    또한 자사의 나쁜 관행은 드 정상화 테이블을 추가, 즉 메타 데이터를 하나 회피 투영 페이로드 하나에. 프로젝션 편집해야에게 유일한 문제는, 새로운 열이 테이블에 추가 될 때마다 작동합니다.

  7. ==============================

    7.난 경우 다른 사람이 같은 상황에이 문제를 해결하기 위해 내 시도를 공유하고 싶습니다.

    난 경우 다른 사람이 같은 상황에이 문제를 해결하기 위해 내 시도를 공유하고 싶습니다.

    나는 제레미 Danyow이 덜 고통스러운 방법입니다 나에게 어떤 제안 무엇을 시작했다.

    // You need to include all fields in the query, just make null the ones you don't want.
    var results = context.Database.SqlQuery<myEntity>("SELECT Field1, Field2, Field3, HugeField4 = NULL, Field5 FROM TableName");
    

    내가 마지막에 AsQueryable ()를 추가, 그래서 내 경우에는, 내가 된 IQueryable <> 결과 객체를 필요로했다. 이것은 물론 내가 어디에요, .Take 호출, 다른 명령을 우리 모두 알고를 추가 할 수 있도록, 그들은 벌금을했다. 그러나주의해야 할 점은있다 :

    이 접근법 System.Linq.EnumerableQuery 를 리턴하면서 정상적인 코드 (context.myEntity.AsQueryable 기본적으로는 ())와, System.Data.Entity.DbSet 를 반환.

    분명히이 수단 내 사용자 지정 쿼리가 즉시 필요 "있는 그대로"실행됩니다 것을하고는 나중에 데이터베이스에 나중에하지 완료 추가 된 필터링.

    그러므로 나는 심지어 [Extent1] 별칭, EF가 생성 정확한 쿼리를 사용하여 모방 엔티티 프레임 워크의 객체를 시도했지만 작동하지 않았다. 결과 객체를 분석 할 때, 그 쿼리는 같은 종료

    [DBO]. TABLENAME] AS [Extent1] 어디에요 FROM (c => ...

    대신 예상의

    [DBO]. TABLENAME] AS [Extent1] FROM WHERE ([Extent1] ...

    테이블이 큰없는 긴만큼 어쨌든,이 작품은, 그리고이 방법은 충분히 빨리 될 것입니다. 그렇지 않으면 수동으로 고전 동적 SQL과 같은 문자열을 결합하여 조건을 추가하는 것보다 더 옵션이 없습니다. 경우의 가장 기본적인 예는 내가 무슨 말을하는지 모르겠어요

    string query = "SELECT Field1, Field2, Field3, HugeField4 = NULL, Field5 FROM TableName";
    if (parameterId.HasValue)
        query += " WHERE Field1 = " + parameterId.Value.ToString();
    var results = context.Database.SqlQuery<myEntity>(query);
    

    당신의 방법은 때때로이 필드를 필요로하는 경우에, 당신은 부울 매개 변수를 추가 한 다음 같은 것을 할 수 있습니다 :

    IQueryable<myEntity> results;
    if (excludeBigData)
        results = context.Database.SqlQuery<myEntity>("SELECT Field1, Field2, Field3, HugeField4 = NULL, Field5 FROM TableName").AsQueryable();
    else
        results = context.myEntity.AsQueryable();
    

    사람이 Linq에 확장이 제대로 원래 EF 객체 인 경우처럼 작동하도록 관리하는 경우, 코멘트 나는 대답을 업데이트 할 수 있습니다하십시오 있도록.

  8. ==============================

    8.나는이 시도 :

    나는이 시도 :

    edmx 다이어그램 (EF 6)에서, 나는 내가 EF에서 숨기기를 원하는 열을 클릭하고 자신의 특성에 당신은 비공개로 자신의 getter 및 setter를 설정할 수 있습니다. 그런 식으로, 나를 위해 작동합니다.

    나는 그것을 암호화와 소금에 절인 비록 암호 필드를 숨기고 싶어 그래서 난 내 JSON에, 난 그냥 그것을 원하지 않았다, 사용자 참조를 포함 일부 데이터를 반환하고, 내가하고 싶지 않았다

    Select(col => new {}) 
    

    그는 특히 관계의 많은 큰 테이블, 작성하고 유지 보수하는 고통 때문이다.

    이 방법의 단점은 당신이 이제까지 모델을 재생성하는 경우, 다시 자신의 getter와 setter를 수정해야 할 것입니다.

  9. from https://stackoverflow.com/questions/8973529/retrieve-an-object-from-entityframework-without-one-field by cc-by-sa and MIT license