2012-05-30 10 views
15

Pracuję nad nowym projektem, który musi używać Linq To SQL. Zostałem poproszony o utworzenie ogólnej lub wielokrotnego użytku klasy Linq to SQL, która może być używana do wykonywania procedur przechowywanych.Tworzenie wielokrotnego użycia Linq do SQL dla procedur przechowywanych

W ADO.Net wiedziałem, jak to zrobić, po prostu przekazując ciąg co chciałem wykonać i mogłem przejść w różnych ciągów dla każdego zapytania muszę uruchomić:

SqlCommand cmd = new SqlCommand("myStoredProc", conn); // etc, etc 

walczę z jak stworzyć coś podobnego w Linq To SQL, jeśli jest to nawet możliwe. Stworzyłem plik .dbml i dodałem do niego moją zapisaną procedurę. W rezultacie, można zwrócić wyniki za pomocą poniższego kodu:

public List<myResultsStoreProc> GetData(string connectName) 
{ 
    MyDataContext db = new MyDataContext (GetConnectionString(connectName)); 
    var query = db.myResultsStoreProc(); 

    return query.ToList(); 
} 

Kod działa, ale chcą mi tworzyć jedną metodę, która będzie zwracać procedurę przechowywaną powiem cokolwiek go uruchomić. Szukałem w Internecie i rozmawiałem z kolegami o tym i nie udało mi się znaleźć sposobu na stworzenie wielokrotnie przechowywanej klasy proc.

Czy istnieje sposób utworzenia klasy wielokrotnego użytku Linq to SQL w celu wykonania zapisanych procesów?

Edit:

Co szukam jest, jeśli istnieje sposób, aby zrobić coś jak poniżej?

public List<string> GetData(string connectName, string procedureName) 
{ 
    MyDataContext db = new MyDataContext (GetConnectionString(connectName)); 
    var query = db.procedureName(); 

    return query.ToList(); 
} 

I Sprawdziliśmy MSDN docs na Linq To Sql a te pokazują tabelę w IEnumerable:

IEnumerable<Customer> results = db.ExecuteQuery<Customer>(
    @"select c1.custid as CustomerID, c2.custName as ContactName 
     from customer1 as c1, customer2 as c2 
     where c1.custid = c2.custid" 
); 

szukam czegoś bardzo rodzajowe, gdzie mogę wysłać ciąg znaków zapisany proc, który chcę wykonać. Jeśli nie jest to możliwe, czy istnieje jakaś dokumentacja dotycząca tego, dlaczego nie można tego zrobić w ten sposób? Muszę udowodnić, dlaczego nie możemy przekazać wartość ciągu o nazwie procedury do wykonania w Linq To Sql

+0

Czy trzeba wykonywać procedur przechowywanych, które nie mogły być modelowane w pliku .dbml? I czy chcesz zwrócić jednostki, które są zmapowane w twoim pliku .dbml? – CodingGorilla

+0

najprawdopodobniej zostaną zmapowane w .dbml, ale myślę, że może być przypadek, w którym nie byłby to – Taryn

+0

. Nie jest to sposób, w jaki LINQ do SQL ma być używany. Pracujesz przeciwko systemowi. Spróbuj pracować tak, jak ma być używana. – usr

Odpowiedz

16

DataContext.ExecuteCommand nie jest dokładnie tym, czego szukasz, ponieważ zwraca tylko wartość int. Zamiast tego potrzebna jest funkcja DataContext.ExecuteQuery, która umożliwia wykonywanie procedury składowanej i zwracanie zestawu danych.

Utworzę częściową klasę dla DBML, w której będzie przechowywana ta funkcja.

public List<T> GetDataNoParams(string procname) 
{ 
    var query = this.ExecuteQuery<T>("Exec " + procname); 

    return query.ToList(); 
} 

public List<T> GetDataParams(string procname, Object[] parameters) 
{ 
    var query = this.ExecuteQuery<T>("Exec " + procname, parameters); 

    return query.ToList(); 
} 

Aby wywołać procedurę przechowywaną byłoby zrobić:

GetDataNoParams("myprocedurename"); 

lub

GetDataParams("myotherprocedure {0}, {1}, {2}", DateTime.Now, "sometextValue", 12345); 

lub

GetDataParams("myotherprocedure var1={0}, var2={1}, var3={2}", DateTime.Now, "sometextValue", 12345); 

Jeśli chcesz procedury bez wartości zwracanej nazwać też jest łatwe, bo jestem pewien, że tak możesz to zobaczyć, tworząc nową metodę, która niczego nie przechowuje/nie zwraca.

Inspiracją była http://msdn.microsoft.com/en-us/library/bb361109(v=vs.90).aspx.

+0

Czy plik DBML ma zamiar powiedzieć "ExecuteQuery ", jaka jest metoda "T", aby dane mogły zostać zamaskowane w instancjach obiektów? – bluevector

+0

Nie, mówisz to, co to jest, gdy go nazwiesz. Moje przykłady zakładają, że masz już obiekty odwzorowane na typy zwracania dla każdej procedury składowanej. Więc jeśli masz procedura składowana, która zwraca klientów i masz typ obiektu klienta, następnie przekazać klienta na T. – Peter

+0

Gotcha. Tak więc nie próbujemy "IQueryable" -jeżeli przechowywane procs i nic nie musi być wszechwiedzące. – bluevector

2

Najprostsza odpowiedź na to pytanie jest to, że można pobrać własność swojej MyDataContextConnection oraz tworzenie i uruchamianie własnych SqlCommand s tak jak w ADO.Net. Nie jestem pewien, czy to będzie służyć twoim celom, szczególnie jeśli chcesz pobrać jednostki z twojego LINQ do modelu SQL.

Jeśli chcesz zwrócić jednostki z modelu, spójrz na metodę DataContext.ExecuteCommand.

+0

Dziękuję za skierowanie w tym kierunku, ale czy możesz podać dodatkowe informacje na temat tego, jak mogę przekazać ciąg znaków z nazwą procedury, którą chcę wykonać . – Taryn

+0

@bluefeet Zobacz odpowiedź Piotra, ma kilka przyzwoitych przykładów. – CodingGorilla

0

Kiedy upuszczamy tabelę lub zapisaną procedurę w naszym pliku .dbml, tworzy ona swoją klasę, która komunikuje się z warstwą danych i naszą logiką biznesową.

w LINQ to SQL musimy mieć storedprocedures lub tabel w pliku .dbml inaczej nie ma sposobu, aby wywołać metodę rodzajową w LINQ do SQL na wywołanie procedury przechowywanej przez przekazanie jej nazwę do metody.

Ale w ADO.Net możemy to zrobić (jak wiecie)

SqlCommand cmd = new SqlCommand("myStoredProc", conn); 
Powiązane problemy