2009-03-16 8 views
7

W bazie danych mam tabelę o nazwie Kontakt. Pierwsza nazwa i inne takie pola ciągów są zaprojektowane do używania typu danych Char (nie mojego projektu bazy danych). Mój obiekt Kontaktuje mapy z typem ciągu we właściwościach. Gdybym chciał zrobić prosty test pobierania obiektu kontaktu przez ID, chciałbym zrobić coś takiego:Jak przyciąć wartości za pomocą Linq do Sql?

Contact contact = db.Contacts.Single(c => c.Id == myId); 
Contact test = new Contact(); 
test.FirstName = "Martin"; 

Assert.AreEqual(test.FirstName, contact.FirstName); 

Wartość contact.FirstName jest „Martin” ze względu na typ char. Gdzie mogę przechwycić właściwość FirstName podczas ładowania? OnFirstNameChanging (wartość ciągu) nie jest wywoływana podczas początkowego obciążenia (kontaktu), ale działa na obiekcie testowym.

Odpowiedz

8

Może mógłbyś umieścić to w częściowej metodzie OnLoaded()? Uwaga: Nigdy tego nie używałem, ale zakładam, że wyglądałoby to tak:

public partial class Contact 
{ 
    partial void OnLoaded() 
    { 
     FirstName = FirstName.Trim(); 
    } 
} 
+0

To działa. Jest to dość łatwe do zrobienia dla każdego pola, ponieważ nie pokazuję wielu pól do wyświetlenia. Dzięki. – Marsharks

+0

Spowoduje to wygenerowanie zdarzenia zmiany właściwości - które może wywołać inne działania - i może spowodować niepotrzebne aktualizacje bazy danych, ponieważ zmienia się wartość właściwości bez wprowadzania jakichkolwiek zmian semantycznych w treści. – tvanfosson

+3

Punktem pytania było znalezienie miejsca na taką logikę (w tym przypadku OnLoaded()); Sama metoda może równie dobrze składać się z "_FirstName = _FirstName.Trim();" aby uniknąć sytuacji, w której propozycja zmieniła strzelanie. –

1
Contact contact = db.Contacts.Single(c => c.Id.Trim() == myId); 

Sprawdź, czy dostawca LINQ tłumaczył to na odpowiedni kod SQL.

+0

Nie sądzę, że problem dotyczył pola Id. – tvanfosson

+1

@tvanfosson - Myślę, że op zamierzał to tylko dla przykładu, nie należy go brać dosłownie. –

6

Jeśli nie możesz zmienić schematu, możesz chcieć, aby projektant wygenerował dostęp jako prywatny/chroniony i utworzyć publiczny akcesor, aby uzyskać właściwość front-end w częściowej implementacji klasy. Następnie możesz przyciąć wartość w access access.

public partial class Contact 
{ 

    public string RealFirstName 
    { 
     get { return this.FirstName.Trim(); } 
     set { this.FirstName = value; } 
    } 

    ... 
} 
+1

Jest to dobre rozwiązanie, ponieważ nie tylko są to pola typu char, ale także są nazywane First_Name. Mogłem więc naprawić wszystkie pola, nie zmieniając ich w moim projektancie obiektów. – Marsharks

+0

Problem polega na tym, że utworzę zapytanie i spróbuję użyć czegoś w rodzaju FullName = c.FirstName + '' + c.LastName. Otrzymałem komunikat Nie można przetłumaczyć wyrażenia i nie mogłem traktować go jako komunikatu o treści lokalnej. – Marsharks

+0

Po zakończeniu filtrowania możesz użyć ToList() w celu wygenerowania faktycznego zapytania, a następnie wybierz z listy wynikowej. Ponieważ są to obiekty w tym miejscu, powinna działać konstrukcja FullName. – tvanfosson

0

Można uruchomić ForEach na swojej liście kontaktów przed próbuje szukać Martin.

var contacts = db.Contacts.ForEach(c => c.FirstName = c.FirstName.Trim()); 
Contact contact = contacts.Single(c => c.Id == myId); 
contact.FirstName // = "Martin" 

Ale ten sposób nie jest bardzo łatwy do utrzymania, jeśli ma być wykonany dla wielu pól.

+0

Co się stanie, jeśli ma 100 000 kontaktów? –

1

To zależy od kontroli nad schematem i kodem.

Jeśli wartości są ustawiane przez wywołanie konstruktora ze wszystkimi parametrami, wykonaj wyrównania itp., Ponieważ są one przypisane do zmiennych składowych.

Jeśli są one przypisane do właściwości (prawdopodobnie z przykładu), zmień akcesor SET, aby zrobił tam przycięcie.

Masz potencjalne problemy, jeśli rzeczywiście chcesz WCZEŚNIONE lub końcowe spacje.

Jeśli nie można zmodyfikować kodu klasy podstawowej, spróbuj użyć klas częściowych lub dziedzicząc z klasy i nadpisując jej właściwości.

Jeśli nie możesz tego zrobić, moją ostatnią sugestią byłoby napisanie klasy fabrycznej, której przekazujesz utworzony obiekt i czyści go zgodnie z regułami, które chcesz.

Powiązane problemy