Realm .NET의 LINQ 지원
Realm으로 쿼리를 만들려면 Realm.All<T>()
메서드를 사용하여 IQueryable<T>
인스턴스를 가져옵니다. 그런 다음 아래 나열된 연산자를 적용할 수 있습니다.
제한 연산자
Where
가 지원됩니다. OfType
는 그렇지 않지만 Realm의 query가 항상 처음에 지정된 클래스의 collection으로 구성되므로 중복될 수 있습니다.
Where
은 술어를 사용합니다. Realm 쿼리에서 조건자에 대해 지원되는 작업을 확인하려면 조건자 작업 섹션을 참조하세요.
예시:
var oldDogs = realm.All<Dog>().Where(dog => dog.Age > 8);
순서 연산자
OrderBy
, OrderByDescending
, Thenby
및 ThenByDescending
이 모두 지원됩니다. Reverse
는 아직 지원되지 않습니다. 현재는 쿼리하는 클래스의 지속형 속성을 기준으로만 순서를 지정할 수 있습니다. 이는 dogs.OrderBy(dog => dog.Owner.FirstName)
등은 아직 지원되지 않음을 의미합니다.
예시:
var contacts = realm.All<Person>().OrderBy(p => p.LastName).ThenBy(p => p.FirstName);
변환 연산자
ToArray
, ToList
, ToDictionary
및 ToLookup
이 모두 지원됩니다. Cast
는 그렇지 않지만 Realm의 query는 항상 처음에 지정된 클래스의 collection으로 구성되므로 중복될 수 있습니다.
예시:
var phoneBook = realm.All<Person>().ToDictionary(person => person.PhoneNumber);
요소 연산자
모든 기본 요소 연산자가 지원됩니다.
First
개인정보 정책에FirstOrDefault
Last
개인정보 정책에LastOrDefault
Single
개인정보 정책에SingleOrDefault
이러한 메서드는 선택적 술어(predicate)를 사용합니다. Realm 쿼리에서 조건자에 대해 지원되는 작업을 확인하려면 조건자 작업 섹션을 참조하세요.
인덱스로 단일 요소에 액세스하는 것은 ElementAt
및 ElementAtOrDefault
에서 지원됩니다.
default(T) 의 표준 C# 동작과 마찬가지로 변형 ...OrDefault
은 일치하는 요소가 없는 경우 단일 null RealmObject
을 반환합니다.
DefaultIfEmpty
은(는) 아직 지원되지 않습니다.
수량자
Any
가 지원됩니다.
All
및 Contains
은(는) 아직 지원되지 않습니다.
Any
은(는) 선택적 술어(predicate)를 사용합니다. Realm 쿼리에서 조건자에 대해 지원되는 작업을 확인하려면 조건자 작업 섹션을 참조하세요.
집계 연산자
Count
가 지원됩니다.
LongCount
, Sum
, Min
, Max
및 Average
는 아직 지원되지 않습니다.
Count
은(는) 선택적 술어(predicate)를 사용합니다. Realm 쿼리에서 조건자에 대해 지원되는 작업을 확인하려면 조건자 작업 섹션을 참조하세요.
술어 작업
일반적으로 Realm의 데이터에 의존하는 조건이 있는 조건자만 만들 수 있습니다. 수업을 상상해 보세요.
class Person : RealmObject
{
// Persisted properties
public string FirstName { get; set; }
public string LastName { get; set; }
// Non-persisted property
public string FullName => FirstName + " " + LastName;
}
이 클래스가 주어지면 FirstName
및 LastName
속성에는 적용되지만 FullName
속성에는 적용되지 않는 조건을 사용하여 쿼리를 만들 수 있습니다. 마찬가지로 [Ignored]
속성이 있는 속성은 사용할 수 없습니다.
현재 속성은 조건의 왼쪽에 있어야 합니다. 이는 다음을 의미합니다.
var oldDogs = realm.All<Dog>().Where(dog => 7 < dog.Age); // INVALID query, do not copy
은(는) 불법이며 이에 상응하는 것으로 변경해야 합니다.
var oldDogs = realm.All<Dog>().Where(dog => dog.Age > 7); // Fixed
관계 연산자
등호 연산자는 모든 속성 유형에 적용할 수 있습니다: ==, !=
또한 숫자 유형에 <, <=, >, >=를 사용할 수 있습니다.
문자열 연산자
문자열에서는 Contains
, StartsWith
및 EndsWith
, Equals
및 Like
을 사용할 수 있습니다.
예시:
var peopleWhoseNameBeginsWithJ = realm.All<Person>.Where(p => p.FirstName.StartsWith("J"));
기본적으로 Realm은 대소문자를 구분하여 비교를 수행하지만 StringComparison.OrdinalIgnoreCase
인수를 제공하여 이를 덮어쓸 수 있습니다. 이전 .NET 프레임워크에서 StringComparison
를 허용하는 Contains
에 대한 오버로드가 없으므로 쿼리 시 사용할 수 있는 도우미 메서드 를 제공합니다.
var peopleWhoseNameContainsA = realm.All<Person>().Where(p => QueryMethods.Contains(p.FirstName, "a", StringComparison.OrdinalIgnoreCase));
Like
쿼리 메서드는 문자열 속성을 패턴과 비교하는 데 사용할 수 있습니다. ?
및 *
는 와일드카드 문자로 허용되며, 여기서 ?
는 1개 문자와 일치하고 *
는 0개 이상의 문자와 일치합니다.
var words = realm.All<Word>().Where(p => QueryMethods.Like(p.Value, "?bc*"));
// Matches abc, cbcde, but not bcd
쿼리 표현식에서 사용되지 않는 경우 Like
는 RegEx를 사용하여 동일한 규칙을 적용합니다.
구성
괄호와 || 및 && 연산자를 사용하여 쿼리를 작성할 수 있습니다.
예시:
var PuppyRexes = realm.All<Dog>().Where(dog => dog.Age < 2 && dog.Name == "Rex");
활동성에 대한 참고 사항
Realm 쿼리는 데이터베이스의 현재 상태를 계속 표현한다는 점에서 live 입니다.
realm.Write(() =>
{
realm.Add(new Person { FirstName = "John" });
realm.Add(new Person { FirstName = "Peter" });
});
var js = realm.All<Person>().Where(p => p.FirstName.StartsWith("J"));
foreach(var j in js)
{
Console.WriteLine(j.FirstName); // ==> John
}
realm.Write(() =>
{
realm.Add(new Person { FirstName = "Joe" });
});
foreach(var j in js)
{
Console.WriteLine(j.FirstName); // ==> John, Joe
}
이는 쿼리 결과를 그대로 가져와 메모리에 보관하는 객체/관계형 매퍼(ORM)의 일반적인 동작과 다릅니다.
그러나 이는 또한 매번 반복할 때마다 표현식을 다시 평가하므로 조건의 양쪽을 변경하면 결과에 영향을 미치는 LINQ to 객체의 동작과는 다릅니다. Realm 쿼리는 첫 번째 실행 시 조건의 오른쪽을 평가합니다. 다음과 같은 쿼리가 있다고 가정해 보겠습니다.
var recentLogEntries = realm.All<LogEntry>().Where(l => l.TimeStamp > DateTime.Now.AddHours(-1));
여기서 recentLogEntries
변수에는 쿼리가 처음 실행된 시간( foreach ToList
TimeStamp
을 통해) 1시간 이전보다 늦은 모든 로그 항목이 포함됩니다. 새로 추가된 로그 항목은 후속 실행에 포함되지만 비교되는 시간은 업데이트되지 않습니다.
아직 지원되지 않음
다음 기능은 아직 지원되지 않습니다. Realm 아키텍처로 인해 필요하지 않은 경우 그 중 일부는 지원되지 않습니다.
그룹화 연산자
GroupBy
은(는) 지원되지 않습니다.
집합 연산자
Distinct
, Union
, Intersect
및 Except
은 지원되지 않습니다.
파티셔닝 연산자
Take
, Skip
, TakeWhile
및 SkipWhile
는 아직 지원되지 않습니다.
이는 ORM을 사용할 때보다 중요하지 않습니다. Realm의 제로 카피 패턴을 고려하면 객체의 속성에 액세스할 때만 데이터베이스에서 데이터를 읽으므로 결과의 일부를 단순히 반복하는 데 드는 오버헤드가 거의 없습니다.
프로젝션 연산자
Select
및 SelectMany
은(는) 아직 지원되지 않습니다.
쿼리 구문과 함께 사용되는 선택 키워드는 일부 파생어가 아닌 RealmObject
자체를 선택하는 한 지원됩니다.
var oldDogs = from d in realm.All<Dog>() where d.Age > 8 select d;
연결 연산자
Concat
은(는) 지원되지 않습니다.
조인 연산자
Realm을 사용할 때는 relational database와 ORM을 사용할 때보다 조인이 덜 중요하다는 점에 유의하세요. 키를 사용하여 관계를 식별하는 대신 관련 객체를 참조하기만 하면 됩니다.
따라서 주어진 클래스
public class Address : RealmObject
{
public string StreetName { get; set; }
public int Number { get; set; }
}
다음과 같이 다른 클래스에서 간단히 사용할 수 있습니다.
public class Customer : RealmObject
{
public string Name { get; set; }
public Address Address { get; set; }
}
이는 C#의 일반 참고처럼 작동하므로 두 Customer
개의 인스턴스에 동일한 Address
객체가 할당되면 해당 주소에 대한 변경 사항이 두 객체에 모두 적용됩니다.