2017-12-20 114 views
7

Niedawno natknąłem poniżej kawałek kodu w naszej aplikacji-1 w indeksie listy w języku C#

var updateDefinition = new UpdateDefinitionBuilder<OverviewProfile>() 
      .Set(a => a.Advisors[-1].IsCurrent, advisor.IsCurrent); 

W powyższym kodzie, Advisors jest List i UpdateDefinitionBuilder jest z kierowcą MongoDB.

Czy możesz podać mi numer -1 w indeksie listy?

Montaż po komentarzach poniżej/odpowiedzi

Klasa OverviewProfile jest jak poniżej:

public class OverviewProfile: BaseInvestorProfile 
{ 
    //Other properties 

    public List<Advisor.View.Advisor> Advisors { get; set; } 
    public OverviewProfile(int id): base(id) 
    { 
     Advisors = new List<Advisor.View.Advisor>(); 
    } 
} 

I to jest ten kod obróbka. Ten kod aktualizuje dane do bazy danych mongo na podstawie warunku. W tej klasie nie ma innych metod, tylko inne właściwości.

Jest to jedna klasa, ale to samo dotyczy właściwości wielu klas, a nawet jeśli dodamy nową właściwość i sprawdzimy, to działa.

+0

To nie powinno w ogóle działać. Zwykle indeks o wartości -1 jest zwracany za pomocą metod takich jak 'InfexOf', aby zwrócić pierwsze wystąpienie konkretnej instancji. -1 oznacza zazwyczaj, że tego przedmiotu nie znaleziono. Poza tym indeks -1 przekazany do 'Listy ' spowoduje 'ArgumentException', ponieważ indeks nie może być mniejszy od zera. – HimBromBeere

+2

Czy możliwe jest, że osoba wdrażająca lub doradcy zastąpiła indeksator nawiasów kwadratowych? Mogę się domyślać, że używają wartości do wszystkich elementów na liście. Ale to naprawdę nieprzyjemne. – LordWilmore

+0

Założę się, że '.Advisors' jest * nie * instancją listy .NET' List '. Jest to specjalna implementacja, która przeciążyła operatora '[index]', tak jak powiedział LordWilmore, i że '-1' odnosi się do ostatniego wpisu na liście. – Michael

Odpowiedz

8

Używasz przeciążenia w postaci UpdateDefinitionBuilder<T>.Set, która oczekuje Expression. To wyrażenie nie jest kompilowane i wykonywane bezpośrednio, ale zamiast tego jest konwertowane na natywną składnię mongodb i jest używane jako część zapytania mongo db (tak samo jak Entity Framework lub inne ORM konwertuje wyrażenia do SQL). W zasadzie mówi "zaktualizuj wszystkie profile przeglądowe i ustaw flagę IsCurrent pierwszego doradcy, która spełnia kryteria do wartości advisor.IsCurrent". Ponieważ mongodb zezwala na indeksy ujemne (czyli - w odniesieniu do końca zbierania) - sterownik C# mongodb może przekonwertować wyrażenie na poprawne zapytanie mongodb (zobacz poniżej aktualizację).

Aktualizacja. Jak podano here, -1 nadal ma specjalne znaczenie dla sterownika mongodb C#.zostanie skonwertowana do positional update operator $:

pozycyjne aktów $ operatora jako zastępczy dla pierwszego elementu pasującej dokument zapytania

Na przykład:

var updateDefinition = new UpdateDefinitionBuilder<OverviewProfile>() 
    .Set(a => a.Advisors[-1].IsCurrent, false); 

colleciton.UpdateOne(c => c.Advisors.Any(r => r.IsCurrent), updateDefinition); 

zostaną przeliczone na coś takiego:

"updates": [{ 
     "q": { 
      "Advisors": { 
       "$elemMatch": { 
        "IsCurrent": true 
       } 
      } 
     }, 
     "u": { 
      "$set": { 
       "Advisors.$.IsCurrent": false // <- your expression 
      } 
     } 
    } 
] 

Jednak punkt o ujemnym wskaźnikiem oznaczającego w stosunku do końca colleciton w MongoDB nadal jest, ponieważ każdy inny ujemny indeks wyjątkiem -1 (na przykład, -2) zostanie przekształcony do zapytania w następujący sposób:

{ "$set" : { "Advisors.-2.IsCurrent" : false} } 
+0

Co byłoby wyrażeniem mongo stworzonym na podstawie tego stwierdzenia? – HimBromBeere

+0

@HimBromBeere Zaktualizowałem odpowiedź, podając więcej informacji na ten temat. – Evk

1

Jeśli w rzeczywistości a.Advisors jest , nie ma sensu. To rzuci ArgumentOutOfRangeException.

Co jest bardziej prawdopodobne, że jest to klasa niestandardowa lub implementacja ponad List<T>, gdzie wartość -1 przekazana do indeksu oznacza coś w rodzaju wartości "domyślnej".

Cokolwiek to jest, myślę, że jest to zły projekt i należy go unikać.

+0

Wystarczy, aby dodać oficjalne odniesienie ... Spójrz na [kod źródłowy] (http://referencesource.microsoft.com/mscorlib/R/0c65bec4d3fac21e.html) –

+0

"Implementacja przez" Listę ' "? Indekser listy nie jest wirtualny, nie można go przesłonić (można go jednak ukryć). – HimBromBeere

+0

* Klasa * może mieć niestandardową implementację, indeksator rzeczywiście może być ukryty za pomocą 'nowego'. @HimBromBeere –