"LINQ to SQL Classes". Jak go prawidłowo definiować?

0

Zacząłem tworzyć dostęp do bazy przez LINQ to SQL. W obiekcie LINQ to SQL Classes dodałem wszystkie tabele powiązane ze sobą wokol tabeli/klasy Pracownika, tzn. Pracownik, DzialFirmy, StanowiskoPracy, Haslo.

Taki wycinek bazy danych służy jako DataContext w repozytorium PracownikiRepository, wydawalo mi sie to wygodniejsze do pozyskiwania NazwDziałów, NazwStanowisk bezpośrednio z obiektu Pracownik. Bo zmapowana klasa Pracownika zawiera teraz nie tylko pola int z numerami id pół: DziałFirmy, StanowiskoPracy i Haslo ale tez zawiera pole typu tych obiektów i ma te obiekty w sobie.

I dopóki korzystałem z repozytorium tylko odczytując dane z bazy to było wygodne ale problem wystąpił w chwili gdy chciałem dodać nowego pracownika. Wyskoczył wyjątek:

An attempt has been made to Attach or Add an entity that is not new, perhaps having been loaded from another DataContext. This is not supported.

doczytałem że chodzi tu o to że dodając nowego Pracownika kompilator "widzi" ze obiekt Pracownik zawiera podobiekty DzialFrimy, StanowiskoPracy itp i czepia się ich że ja chce je dodać jako nowe a one już istnieją w bazie. Tak jakby metoda:

        public void Add(Pracownik entity)
        {
            db.Pracownicy().InsertOnSubmit(entity);
            db.SubmitChanges();
        } 

nie chiała dodac jako nowy tylko Pracownik entity ale i jego podobiekty również jako nowe.

I teraz pytanie:

Czy 1 obiekt LINQ to SQL classes ma zawierać tylko jedną tabele? Wtedy dodając nowego pracownika operuje tylko na numerach id jego ewentualnych podobiektow a nie na całych podobiektach? Czy to normalne ze wtedy w jednym presenterze bede mial tyle repozytoriow z ilu tabel bede korzystal w danym oknie? Np. Takie okno AddEditPracownik gdzie wpisuje dane nowego albo edytuje istniejącego pracownika bedzie zawieral repozytoria: Pracownik, Dzialfirmy, StanowiskoPracy itd, zeby wyswietlic np. nazwe dzialu do jakiego przypisac nowego pracownika.

0

Wygląda na to, że tworzysz obiekt w innym kontekście niż ten, w którym chcesz go zapisać. Generalnie za mało kodu podałeś, żeby to ustalić.

LINQ to SQL to już nierozwijana technologia, czemu chcesz się tego uczyć?

0

Sprawa częściowo wyjaśniona, dla dodawanego nowego pracownika przypisywałem gotowe obiekty StanowiskaPracy i DzialuFirmy, jak zacząłem ustawiać tylko id, a pol typu StanowiskaPracy i DzialuFirmy wogólnie nie ustawiałem wszystko zaczęło działać.
Tego też testy nie wychwyciły, w wynikach testów było wszystko ok, ale w sumie nie testowałem przypadku gdzie dodaje podobiekt a nie same id, tak wyglada mój test:

 
        [SetUp]
        public void Setup()
        {
            mockPracownikDataContext = new Mock<IDanePodstawoweDataContext>();
            stubdataContextWrapper = new StubDanePodstawoweDataContextWrapper(mockPracownikDataContext.Object);
            pracownikRep = new PracownikRepository(stubdataContextWrapper);

            //Tworzenie pojedynczych pracowników p1, p2, p3, p4, p5
            Pracownik p1 = new Pracownik
            {
                idPracownika = 5,
                Imie1 = "Admin",
                Nazwisko = "Adminowicz",
                Login = "Admin Adminowicz",
                mailFirmowy = "[email protected]",
                telFirmowy1 = "123456789",
                idPrzelozonego = 113,
                idDzialu = 4,
                idStanowiska = 1,
                DataZatrudnienia = new DateTime(2014, 05, 19),
                idPlci = 1
            };
            //analogicznie 4 pozostali pracownicy

            List<Pracownik> pracownicy = new List<Pracownik> { p1, p2, p3, p4, p5 };
            mockPracownikDataContext.Setup(x => x.Pracownicy()).Returns(new StubPracownikTable(pracownicy));
        }

        [Test]
        public void DodaniePracownikaTest()
        {
            Assert.AreEqual(5, pracownikRep.Count());           
            Pracownik nowy = new Pracownik
            {
                Imie1 = "Nowy", Nazwisko = "Nowiński", Login = "Nowy Nowiński",
                mailFirmowy = "[email protected]", telFirmowy1 = "506000666", idPrzelozonego = 113,
                idDzialu = 4, idStanowiska = 1, DataZatrudnienia = new DateTime(2014, 06, 26), idPlci = 1
            };
            pracownikRep.Add(nowy);
            Assert.AreEqual(6, pracownikRep.Count());
        }
somekind napisał(a):

(...) LINQ to SQL to już nierozwijana technologia, czemu chcesz się tego uczyć?

Bo jest dla mnie najprostsza w tej chwili i najlepiej opisana.

1 użytkowników online, w tym zalogowanych: 0, gości: 1