Linq 쿼리 결과를 사전으로 변환


346

Linq to SQL을 사용하여 데이터베이스에 일부 행을 추가하고 싶지만 행을 추가하기 전에 "맞춤 검사"를 수행하여 들어오는 행을 추가, 교체 또는 무시해야하는지 알고 싶습니다. 클라이언트와 DB 서버 간의 트래픽을 가능한 한 낮게 유지하고 쿼리 수를 최소화하고 싶습니다.

이 작업을 수행하기 위해 유효성 검사에 필요한 정보를 최소한으로 가져오고 프로세스 시작시 한 번만 가져오고 싶습니다.

나는 이와 같은 일을 생각하고 있었지만 분명히 작동하지 않습니다. 누구나 아이디어가 있습니까?

Dictionary<int, DateTime> existingItems = 
    (from ObjType ot in TableObj
        select (new KeyValuePair<int, DateTime>(ot.Key, ot.TimeStamp))
    )

마지막에 가지고 싶은 것은 TableObject에서 전체 ObjectType 객체를 다운로드 할 필요없이 Dictionary입니다.

나는 또한 다음 코드를 고려했지만 적절한 방법을 찾으려고 노력했다.

List<int> keys = (from ObjType ot in TableObj orderby ot.Key select ot.Key).ToList<int>();
List<DateTime> values = (from ObjType ot in TableObj orderby ot.Key select ot.Value).ToList<int>();
Dictionary<int, DateTime> existingItems = new Dictionary<int, DateTime>(keys.Count);
for (int i = 0; i < keys.Count; i++)
{
    existingItems.Add(keys[i], values[i]);
}

답변:


633

사용해보십시오 방법 과 같이 :ToDictionary

var dict = TableObj.ToDictionary( t => t.Key, t => t.TimeStamp );

2
@pawan, 열거의 각 요소에 대한 자리 표시 자이며 열거의 개체 유형을 취합니다.
tvanfosson

1
@pawan-맞지 않는 것 같습니다. 내가 기대하는 var servers = list.Select( s => new { s.ProjectName, Url = "tcp://" + s.BuildMachineName + ":" + s.PortNumber + "/CruiseManager.rem" } ).ToDictionary( s => s.ProjectName, s.Url ); 이 프로젝트 이름 / URL 쌍 프로젝트 이름으로 키가 사전을 만듭니다.
tvanfosson

3
.Select( t => new { t.Key, t.TimeStamp } )표현이 필요한 이유는 무엇 입니까?
벤 콜린스

9
@ BenCollins : 중간으로 .Select인해 생성 된 SQL이 모든 열을 선택하는 대신 Key 및 TimeStamp 만 선택 한다고 생각합니다 .
Joey Adams

1
SelectLinq to SQL 대신 Linq to Object를 수행하는 경우이 중개자를 생략 할 수 있습니다.
Pac0

119

당신의 예를 보면, 이것이 당신이 원하는 것이라고 생각합니다.

var dict = TableObj.ToDictionary(t => t.Key, t=> t.TimeStamp);

와우 ... 그것은 간단 할 수 있습니다 ... 프로그래밍에 익숙하지 않기 때문에, 나는 그것을 시도하고 약간의 프로파일 링을 수행하여 후드 아래에서 전체 객체의 히트를 얻지 않도록합니다. 계속 게시하겠습니다.
Tipx

1
방금 확인 했어요 슬프게도 TableObj를 가져 오는 동안 db에서 모든 객체를 가져 와서 trafic 적중을 얻습니다. 또한 두 번째 방법으로 게시하고 피하고 싶었던 쿼리를 확인했으며 필요한 항목 만 얻었습니다. 물론 2 개의 쿼리를 수행하므로 서버 자체는 두 번 테이블을 검색해야하지만 객체 매핑은 간단합니다.
Tipx

7
가능한 작업 : TableObj.Select (t => new {t.Key, t.TimeStamp}). ToDictionary (t => t.Key, t => t.TimeStamp); LinqToSql은 (선택에서) 두 가지만 원한다는 것을 알 수있을 것입니다. ToDictionary ()의 세부 사항을 파고 들기에 충분히 똑똑하지는 않습니다.
Talljoe 2018 년

1
좋은! 결과 쿼리는 다음과 같습니다. SELECT [t0]. [Key], [t0]. [TimeStamp] FROM [TableObj] AS [t0]. 나는 이것에 대한 크레딧을 받고 싶지 않기 때문에 그것을 anwser로 게시하십시오! - P
Tipx

8

다음을 시도하십시오

Dictionary<int, DateTime> existingItems = 
    (from ObjType ot in TableObj).ToDictionary(x => x.Key);

또는 본격적인 유추 버전

var existingItems = TableObj.ToDictionary(x => x.Key);

anwser JaredPar에 감사드립니다. 나는 그런 것에 대해 가르쳤지만 이것이 ObjType 유형의 전체 객체를 반환한다고 생각하며 전체 객체를 다운로드하지 않아도됩니다.
Tipx

@Tipx, 필터링 대상에 대한 정보를 제공 할 수 있습니까? 필터 절을 추가하는 것도 가능하지만 중요한 것은 귀하의 질문에서 알 수 없습니다
JaredPar

"새 행"을 추가해야하는지, 무시하거나 다른 행을 바꾸어야하는지 알아야하는 것은 개체의 타임 스탬프입니다. DB의 객체에는 유효성 검사에 필요하지 않은 많은 필드가 있으며 전체 객체를 가져 오는 성능을 높이고 싶지 않습니다. 간단하게하기 위해 BD에 20 개의 열, 10 만 개의 행이있는 테이블을 얻었으며 처음 2 열의 값을 사용하여 사전을 추출하고 싶습니다.
Tipx

방금 해당 코드로 생성 된 서버 쿼리를 확인했으며 아마 아시다시피 전체 개체를 가져옵니다.
Tipx

0

네임 스페이스 사용

using System.Collections.Specialized;

DataContextClass 인스턴스 만들기

LinqToSqlDataContext dc = new LinqToSqlDataContext();

사용하다

OrderedDictionary dict = dc.TableName.ToDictionary(d => d.key, d => d.value);

값을 검색하려면 네임 스페이스를 사용하십시오.

   using System.Collections;

ICollection keyCollections = dict.Keys;
ICOllection valueCollections = dict.Values;

String[] myKeys = new String[dict.Count];
String[] myValues = new String[dict.Count];

keyCollections.CopyTo(myKeys,0);
valueCollections.CopyTo(myValues,0);

for(int i=0; i<dict.Count; i++)
{
Console.WriteLine("Key: " + myKeys[i] + "Value: " + myValues[i]);
}
Console.ReadKey();

대한 Multilple 키 ?
Kiquenet
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.