2012-12-28 20 views
5

Mam funkcję, która zwraca obiekt reprezentujący rekord w mojej bazie danych plus dodatkowe kolumny. Zamiast tworzyć oddzielną klasę dla tego obiektu Zastanawiałem się, czy istnieje inny sposób, na przykład:Zwróć typ danych zapytania linq

public object GetRecord(string key) 
{ 
    var item = select new {column1, column2}; 

    return item; 
} 

public void main() 
{ 
    var item = GetRecord(1); 

    // I want to be able to reference column1 on item. 
    var x = item.column1; 
} 

Odpowiedz

8

Tak, istnieją inne sposoby (w rzeczywistości kilka), ale zdecydowanie sugeruję, aby nie używać żadnego z nich. Najlepszym rozwiązaniem w przypadku tego przypadku jest utworzenie nowego niestandardowego typu, który zawiera dane, które posiadasz. Będzie to zdecydowanie najbardziej dostępna opcja.

Anonimowe typy zostały zaprojektowane specjalnie do stosowania w ramach pojedynczej metody. Walczysz z konstrukcją funkcjonalności, aby zrobić inaczej, a więc będzie to trudne do zrobienia, najprawdopodobniej stracisz Intellisense, wydajność najprawdopodobniej ucierpi, a biedny sap, który musi powrócić i utrzymać kod będzie nie mam pojęcia, co się dzieje i jak dostosować zapytanie.

Podstawowym problemem większości alternatywnych rozwiązań jest utrata sprawdzania czasu kompilacji. Jeśli zapytanie usuwa parametr, dodaje parametr, zmienia typ itp. Kod, który go używa, nie ma możliwości poznania. Pisząc kod, aby użyć kwerendy, nie masz możliwości dowiedzenia się, jakie są wszystkie dane, jakie są ich typy, jakie są imiona zmiennych itp. Trzeba się martwić o literówki w nazwach zmiennych, które kompilator może złapać, i będziesz konsekwentnie trzeba patrzeć na wewnętrzne działania metody, która generuje zapytanie. Tracisz możliwość traktowania go jako czarnej skrzynki lub abstrakcji, co jest znaczące.

Jeśli niepokoi Cię czas i wysiłek potrzebny do utworzenia tych niestandardowych typów, istnieje szereg automatycznych narzędzi zaprojektowanych do generowania takich klas na podstawie tabel bazy danych lub innych źródeł.

+1

+1, Nie widzę powodu, aby _nie_ tworzyć typu niestandardowego. –

6

Jeśli jest .net 4.0 Użytkowanie dynamic słowa kluczowego.

public dynamic GetRecord(string key) 
{ 
    var item = select new {column1, column2}; 

    return item; 
} 
+0

Używam dynamiczny, ale zakładam, że nazwa kolumny wi Nie pojawię się w intellisense. ale będzie działać w czasie wykonywania. – Arcadian

+0

Jeśli masz inny zakres, w którym utworzyłeś swój typ dynamiczny, intellisense nie będzie działać. –

+0

Dla intellisense należy użyć typu betonu (którego nie można zmienić w klauzuli select). Zobacz odpowiedź Felipe na ten temat. – Tilak

2

Tylko uzupełniając inne odpowiedzi, możesz również użyć Generics, aby to zrobić. coś takiego:

public T GetRecord<T>(string key) 
    where T : IAnyInterfaceWithProperties, new 
{ 
    var item = select new T { PropertyOfInterface = value, Property2 = value2 }; 

    return item; 
} 
+1

To jest pełne błędów składniowych. Umieść ograniczenie "new" po ograniczeniu interfejsu, usuń rzutowanie na 'T' i' wybierz'. – Adam

+0

Dziękuję za porady @codesparkle. Myślałem w tym przypadku, naprawdę potrzebujemy słowa kluczowego "select"? –

3

Także jeśli jest .net 4.0 można użyć Tuple<object,object> następnie odwołać go item.Item1. Możesz używać pisania obiektów zamiast po prostu object.

public Tuple<Column1Type,Column2Type> GetRecord(string key) 
{ 
    var item = select new Tuple<Column1Type,Column2Type>(column1, column2); 

    return item; 
} 
1

Możesz rozważyć użycie biblioteki POCO do tego - zrobi dokładnie to, co chcesz.

Można toczyć własną rękę lub skorzystać z jednego, który jest już dostępny:

http://code.google.com/p/dapper-dot-net/

Twój kod będzie wtedy wyglądać tak:

var result = connection.Query("select col1, col2 from table1"); 

var x = result[0].col1; 

Drapper pozwala także mają silne typ np .:

var result = connection.Query<myType>("select col1, col2 from table1"); 

' Now result is a list of myType 
Powiązane problemy