2012-03-05 2 views
0

저는 일반적으로 SQL 쿼리에 Entity Framework를 사용합니다. 이는 강력하게 형식화되고 유지 보수가 가능한 방식으로 동적으로 쿼리를 구성 할 수있게 해줍니다.
그러나 지금은 공간 쿼리를 사용하는 프로젝트를 진행하고 있습니다. 대부분의 쿼리는 주어진 좌표에서 시간 또는 거리에 따라 결과 집합을 출력합니다. 그러나 STDistance에 의한 정렬은 쿼리가 10 배 느려지는 것을 발견했습니다. (실제로는 "주문자"이외에 다른 테이블에 가입하면 속도가 느려집니다).NET의 SQL 쿼리

직접 쿼리를 최적화 할 수 있었지만 성능을 다시 가져올 수는 있지만이 쿼리를 생성 할 수는 없습니다 Entity Framework에서.

그래서 나는 EF에서 생성 된 "시간별 주문"쿼리 세트와 SQL 서버의 저장 프로 시저로 "거리 별 주문"쿼리 세트를 갖게 될 수도 있습니다. 문제는 기본적으로 후자의 쿼리 집합이 문자열 연결 (SP 또는 C# 중 하나)을 통해 만들어야한다는 것입니다.

나는 몇 년 동안 SQL 문자열 연결에서 벗어나려고 노력해 왔으며 이러한 ORM 프레임 워크는 99 %의 쿼리에 유용하지만 나는 항상 최적의 쿼리를 얻기 위해 문자열 concanenation으로 되돌아 가야한다. 서버로 보냈습니다. 이것은 유지 보수의 악몽이다.

문자열 연결은 템플릿 엔진을 사용하여 ASP.NET에서 해결되었으므로 기본적으로 html 문자열을 만들 수 있습니다. 누구든지 SQL 문자열에 대한 그런 해결책을 알고 있습니까? 어떤면에서는 다소 지저분하지만 최적의 쿼리를 허용합니다. 내 관점에서이보다 더 잘

  • 문자열 CONCAT가 저장된 프로 시저에있을 것입니다
  • C#에서 문자열 CONCAT 가능한 모든 입력을 포함하는 저장 발동에 중복 된 코드의
  • 대중을 만들 수 있습니다
  • LINQ 쿼리 매개 변수 sub-optimal SQL

나는이 일반적인 문제에 대한 귀하의 생각과 내가 제안한 해결책에 대해 어떻게 생각하는지 알고 싶습니다.
감사합니다 Kris

+0

, LINQ는 성능 설계되었습니다 매우 많은 것을 염두에 두십시오. 쿼리 최적화가 완료되었으며 LINQ에서 사용할 수 있습니다. 내가 붙어있을거야. 오더 비. – SkonJeet

+0

그러나 LINQ-to-Entities 결과를 사용하면 최적화 된 SQL 쿼리보다 10 배 느린 쿼리가 생성됩니다. (170ms가 아닌> 1.2 초) – krisdyson

답변

0

아마도 T4 템플릿을 사용하여보기 (및 해당 쿼리)를 생성하는 옵션이 될 수 있습니다. 템플릿을 수정하거나 생성 된 출력을 선택적으로 무시할 수 있습니다 (템플릿을 수정해야 할 수도 있음).

Microsoft는이 목적으로 T4 template을 제공합니다 (해당 시나리오에 해당하는 내용이 확실하지 않으므로 코드를 먼저 사용하지 않는다고 가정).

부수적으로보기를 사전 컴파일하면 런타임시보기를 생성 할 필요가 없기 때문에 빠른 시작을 제공합니다.

0

어려운 질문입니다.

모든 종류의 EF orm은 항상 수작업으로 만들어진 SQL보다 느립니다. 따라서 우리는 이러한 SQL 쿼리를 수동으로 생성하고 관리해야합니다.이 수동으로 SQL에 자신의 LINQ를 작성, 컴파일시

  • 에서 그 발동을 생성하는 그들에 발동을
  • 사용하는 템플릿 엔진을 SQL 문자열 연결에
  • 쓰기 "스마트 발동"을 쓰기
    1. 을 수행 할 수 있습니다 제공자가 쿼리의 런타임 생성을 위해

    이들 모두는 단점과 단점을 가지고 있지만, 단 단위 테스트 범위가 충분하다면 누군가가 이름을 바꾼 명백한 오류로부터 당신을 보호해야합니다 데이터베이스의 ld.

  • 1

    최신 Entity Framework Beta을 확인하셨습니까? 공간 데이터 유형을 지원해야합니다.

    또한 SQL 쿼리를 동적으로 작성하려면 PetaPoco's SQL Builder을 확인하십시오. 사이트에서 몇 가지 예 :

    예 1 :

    var id=123; 
    var a=db.Query<article>(PetaPoco.Sql.Builder 
        .Append("SELECT * FROM articles") 
        .Append("WHERE [email protected]", id) 
        .Append("AND date_created<@0", DateTime.UtcNow) 
    ) 
    

    예 2 :

    var id=123; 
    var sql=PetaPoco.Sql.Builder 
        .Append("SELECT * FROM articles") 
        .Append("WHERE [email protected]", id); 
    
    if (start_date.HasValue) 
        sql.Append("AND date_created>[email protected]", start_date.Value); 
    
    if (end_date.HasValue) 
        sql.Append("AND date_created<[email protected]", end_date.Value); 
    
    var a=db.Query<article>(sql) 
    

    예 3 :

    제 생각에는
    var sql=PetaPoco.Sql.Builder() 
        .Select("*") 
        .From("articles") 
        .Where("date_created < @0", DateTime.UtcNow) 
        .OrderBy("date_created DESC");