2010-02-02 4 views
1

아마도 원래의 질문은 너무 많은 불필요한 세부 사항으로 인해 너무 오래 지속되었다고 생각합니다. 따라서 이것은 단순화하려는 시도입니다.Linq에서 SQL 로의 엔티티 캐싱/변경 추적 동작을 오버라이드

다음 작업 중을 수행 할 수있는 방법을 찾고 있습니다. 나는 오직 하나만 할 필요가 있습니다. 누구라도이 중 하나에 대한 답을 알고 있다면 답장하십시오. DataContext

  • 풀 엔티티를 ExecuteQuery 또는 ExecuteMethodCall를 통해 그 실체를 추적하지 않고 : 그래서, SQL Linq에에서 다음 중 하나를 수행 할 수 있습니다?

  • 호출 ExecuteQuery 또는 ExecuteMethodCall 나는 항상 그 실체가 이미 검색했다하더라도, 데이터베이스에서 검색 결과의 신선한 사본을 받아 신원 캐시에 이미 보장?

  • Linq to SQL은 특정 엔티티 유형에 대한 변경 추적을 수행하지 않지만 다른 유형의 변경 사항 추적은 허용합니까?

제한 :

  • Refresh 방법은 밖으로 질문; 엔티티의 수가 상당히 많아서 성능상의 재앙이됩니다.

  • 이 나는 ​​단순히 DataContext 쿼리가 실행 된 후 true로 다시 설정을 허용하지 않기 때문에, false-ObjectTrackingEnabled를 설정하고, 나는 개체의 일부 추적해야 할 수 없습니다.

  • 또한 원래 DataContext을 버리고 새 것을 사용할 수 없습니다. 나는 거래의 중간에 이것을 할 수 있어야한다.


이것은 심각한 문제가되기 시작하고, 난 정말 기본 동작이 잘못 생각하고 있다고 생각. 임시 쿼리 나 저장 프로 시저를 실행하면받은 결과가 해당 쿼리에서 반환 한 정확한 결과가 될 것으로 예상됩니다. 단지 의미가 있습니다. 오래된 엔티티 엔티티가 필요하다면 왜 데이터베이스로 돌아가서 가져올 수 있습니까?

현재로서는 (a) 특별히 쿼리에 대해 새 DataContext을 만들고 트랜잭션 격리 수준을 무시하거나 (b) 반환 유형을 해당 엔티티와 동일한 "DTO"로 설정하십시오. 모든 방법이 있지만 [Table] 특성이없는 경우 AutoMapper를 사용하여 원본 엔터티에 매핑하십시오. 이 두 가지 모두 끔찍한 해킹처럼 보입니다.

누군가가이 수수께끼에 어떤 제안을 주셔서 감사합니다.

답변

3

저는이 문제에 대해 장기적인 해결 방법을 제안했습니다. 완벽하게 이상적은 아니지만 지금까지 채용하는 것이 상대적으로 힘들었으며 대안보다 훨씬 덜 무서웠습니다.

어쨌든 이러한 쿼리는 순수 SQL입니다. 인라인 SQL의 경우 모두 이거나 저장 프로 시저의 경우 ExecuteMethodCall입니다. 인스턴스를 원할 때 "원시"ADO.NET으로 드롭 다운하기로했습니다. DataContext 특정 개체에 대해 알아야합니다. 물론

, IDataReader에서 IDbCommand 인스턴스 및 수동 매핑의 무리와 거래를해야하는 끔찍한 것, 그래서 노출, 나를 위해 무거운의 대부분을 할 수있는 라이브러리를 코딩 오늘 아침에 몇 시간을 보냈다 IDbCommand에 "유창한"래퍼라는 용어를 사용하고, MetaModel을 사용하는 자동 LinqDataReaderMapper을 사용하므로 수정하지 않고 기존 엔티티를 사용할 수 있으며 오버로드 된 확장 메서드를 사용하여 더 간단한 쿼리를 작성할 수 있습니다.

var results = context.Connection 
    .Command("SELECT Column1, Column2 FROM Table " + 
      "WHERE FilterColumn1 = @Param1 AND FilterColumn2 = @Param2") 
    .Parameters(
     p => p.Name("Param1").Value(someValue), 
     p => p.Name("Param2").Value(someOtherValue)) 
    .ExecuteReader() 
    .MapWith(context.Mapping).To<MyEntity>(); 

또는 그냥이 : 하루의 끝에서

, 나는 이런 식으로 뭔가를 쓰고 있어요 내가 그것을 위해 전체 코드를 게시하지 않을거야

var results = context 
    .ExecuteQueryRaw<MyEntity>(CommandType.StoredProcedure, "SomeProc", 
     new { Param1 = someValue, Param2 = someOtherValue }); 

- 그것은 꽤 길고 나는 단지 tl인데,이 시점에서이라고 말하면됩니다.하지만 주요 아이디어는이 둘 모두가 IEnumerable<MyEntity>을 돌려주고, IDataReader에서 직접 복사되기 때문에 본질적으로 같습니다. 분리 된 개체 - DataContext은 그들에 대한 직접적인 지식이 없으므로 결과를 가로 채거나 사실 이후에 추적 할 수 없습니다.

그래도 부분적으로 문제가 해결되었지만 DataContext을 실행하면 더 나아질 수 있습니다.

0

LINQ 쿼리에서 결과에 대한 새 개체를 구성하면 변경 내용이 추적되지 않습니다. 나는 이것이 당신이 당신의 대답에서 두 번째 예에서 무엇을 본질적으로 생각

using (NorthwindDataContext context = new NorthwindDataContext()) 
{ 
    var a = from c in context.Categories 
    select new Category 
    { 
    CategoryID = c.CategoryID, 
    CategoryName = c.CategoryName, 
    Description = c.Description 
    }; 
} 

: 그래서 당신은, 같은 (here의 코드)를 업데이트 할 필요가 없습니다 당신이 당신을 알고 값을로드하기 위해 기존의 DataContext를 사용할 수 있습니다 , 나는 단지 그것이 작동하고 나쁜 생각이 아니라는 것을 확인하고 싶다.

또, 내 이해는 어떠한 경우에도 대규모의 단일 DataContext를 사용해서는 안된다는 것입니다. DataContext는 실제로 전 세계가 아닌 Unit-of-Work 레벨 콜렉션입니다. 따라서 읽기 전용 유형의 데이터와 업데이트 할 수있는 데이터에 별도의 DataContext를 사용하면 완벽하게 이해할 수 있습니다 (어떤 것이 미리 예측할 수없는 경우가 아니라면).

+0

답해 주셔서 감사합니다. 트랜잭션은 실제로 하나의 작업 단위이며 중간에 별도의 'DataContext'를 사용하면 DTC로 승격됩니다. 컬럼 데이터로부터 새로운 객체를 생성하는 것은 좋은 지적이지만 유감스럽게도 데이터베이스에서 검색된 원래의 엔티티는 여전히 캐시됩니다 - 그것은 추적되지 않은 복사본에 대한 변경 일 뿐이므로 오래된 것을 해결하지 못합니다 - 데이터 문제. – Aaronaught

+0

그래, 나는 DTC에 승진시키는 것이 무슨 뜻인지 안다. 그것은 괴롭다. 귀하의 방법은 지금 당장 유일하게 실행 가능한 경로일지도 모릅니다. – technophile

관련 문제