2011-03-09 3 views
2

EF4에서 암호화 된 열을 구현하고 CTP5 기능을 사용하여 POCO를 사용하여 데이터베이스를 쿼리 할 수 ​​있습니다. 죄송합니다. 많은 말입니다.하지만 아래에서 희망과 문제점을 설명 할 수 있기를 바랍니다.LINQ to Entities 쿼리에서 쿼리 가로 채기를 구현하려면 어떻게해야합니까? (C#)

그래서

, 배경의 비트, 그리고 지금까지 내 진행 :

의도는 당신이 우리의 DAL를 사용하지 않고 테이블을 조회하면 다음 데이터는 쓰레기입니다,하지만 난 개발자들이 걱정하고 싶지 않아 데이터가 암호화되는 경우/때/방법.

이 단계에서는 모든 문자열 열이 암호화된다는 가정하에 작업하고 있습니다.

이제 Objectmaterialized 이벤트를 사용하여 데이터를 반환하고 SavingChanges 이벤트를 사용하여 데이터를 커밋하는 데 성공적으로 구현했습니다. 거기에

public class Thing 
{ 

    public int ID { get; set; } 
    [Required] 
    public string Name { get; set; } 
    public DateTime Date { get; set; } 
    public string OtherString { get; set; } 
} 

아래 쿼리가 필요한 모든 값을 반환하고 POCO이 구체화이 데이터 삭제 :

그래서 다음 클래스를 부여. myDbContext.Things가
다음 호출 (이름 및/또는 OtherString 값을 클리어 문자열 데이터) Things.Add()
Thing 인스턴스를 전달 마찬가지로 DbSet<Thing>

이다

var things = from t in myDbContext.Things 
      select t; 

myDbContext.SaveChanges()은 문자열이 데이터 저장소에 도착하기 전에 암호화합니다.

지금 내가 가지고있는 문제는이 쿼리에 있습니다

var things = from t in myDbContext.Things 
      where t.Name == "Hairbrush" 
      select t; 

이 암호화되지 않은 값 결과는 DB에 암호화 된 값과 비교된다. 분명히 데이터베이스에서 모든 레코드를 가져 와서 구체화하고 제공된 Where 절을 기반으로 결과를 필터링하지 않으려 고합니다. 그래서 내가해야 할 일은 다음과 같습니다. 쿼리를 가로 채어 임의로 암호화하여 다시 작성합니다. Where 절의 문자열 그래서 내가 검토 한 :

  • 쿼리 공급자 작성,하지만 적합한 솔루션은 아닌 것 같아 ... (이것은 무엇입니까?)에 대한 내 자신에 IQueryable 래퍼를 작성
  • 표현식을 캡처 할 DbSet은 표현식 트리 방문자를 사용하여 실행 한 다음 새 표현식을 DbSet으로 전달합니다. ...

두 가지 모두 시도가 다소 실종되었습니다! 나는 조금 더 깔끔하게 느껴졌고 앞으로는 다른 개발자들에게 더 분명해질 것이라고 생각하는 두 번째 해결책을 선호한다. 그러나 나는 더 좋은 옵션과 함께 가면 행복하다 !!

내가 고민하는 주요한 것은/LINQ식이 개체에 적용될 때입니다 ... 나는 내가 표현식이 IQueryable 개체에서 실행되는 위치에 대해 혼란스러워했습니다. 내 래퍼에서 어떤 식으로 구현할 필요가 있는지 확실하지 않아 전달되는 식을 잡아서 조작해야합니다.

나는 여기에서 꽤 명백한 무엇인가 놓치고있다라고 확신한다. 그리고 나는 그 전구를 기다리고있다. .. 그러나 그 오지 않는다!!

도움을 주시면 매우 감사하겠습니다!

+2

SQL Server 2008과 투명 데이터 암호화는 어떻게 사용합니까? –

답변

2

생각. 결국 Where 메서드를 구현하는 래퍼 클래스를 사용했지만 IQueryable을 완전히 구현하지는 않았습니다. LINQ는 여전히 클래스에 대해 실행합니다 (최소한 내가 원하는/필요로하는 정도까지) LINQ의 식으로 Where 메서드를 호출합니다.

그런 다음이 ExpressionTree를 통과하고 새로운 expressiontree를 내부 DbSet으로 전달하기 전에 암호화 된 값으로 문자열을 대체합니다. 결과를 반환합니다.

매우 조잡하고 제한이 있지만 문제없이 특별한 상황에서 작동합니다.

감사합니다, 벤

0

당신은 QueryInterceptor 속성을 사용해야합니다. 여기 또는 Google에서 검색하고 사용 방법에 대한 예제를 찾으십시오.

코드 조각 : 난 당신이 내 최종 솔루션이 무엇인지 알려 줄

[QueryInterceptor("Orders")] 
public Expression<Func<Order, bool>> FilterOrders() 
{ 
    return o => o.Customer.Name == /* Current principal name. */; 
} 

// Insures that the user accessing the customer(s) has the appropriate 
// rights as defined in the QueryRules object to access the customer 
// resource(s). 

[QueryInterceptor ("Customers")] 
public Expression<Func<Customer, bool>> FilterCustomers() 
{ 
    return c => c.Name == /* Current principal name. */ && 
       this.CurrentDataSource.QueryRules.Contains(
       rule => rule.Name == c.Name && 
         rule.CustomerAllowedToQuery == true 
      ); 
} 
+0

안녕하세요 Davide, 저는 QueryInterceptor를 살펴 봤지만 WCF Data Services를 사용할 때만 관련이있는 것 같습니다. 데이터 서비스를 구현하는 것이 유일한 옵션 인 경우 그렇게 할 수는 있지만 가능한 경우이 옵션을 사용하지 않는 것이 좋습니다. 그렇다면 QueryInceptor를 구현하는 방법을 알 수 없습니다. – Ben

+0

WCF 데이터 서비스의 기능입니다. –

0

당신은 사용할 수 있습니다 데이비드 파울러의 쿼리 인터셉터 :

https://github.com/davidfowl/QueryInterceptor

하나의 사용의 예 :

된 IQueryable Q = ...; IQueryable modifed = q.InterceptWith (new MyInterceptor());

그리고 클래스 MyInterceptor의에

!

보호 재정의 표현 VisitBinary (BinaryExpression을 노드) { 경우 (node.NodeType == ExpressionType.Equal) { // 변경 ==를 = 반환 Expression.NotEqual (node.Left, node.Right); } return base.VisitBinary (node); }

관련 문제