19. juni 2010 - 13:20Der er
10 kommentarer og 1 løsning
Linq to Sql partial class return value?
Er i gang med at lære Linq to Sql
Jeg har bygget en række entities ved hjælp af Object relational designer.
Herefter har jeg lavet en partial class tblKatalog. De simple Select operationer går fint men jeg mangler forståelse for de lidt mere komplicerede som f.eks. denne:
public static IEnumerable<tblKatalog> SelectWhereID(int ID) { DataClassesDataContext db = new DataClassesDataContext(); var query = db.tblKatalogs .Where(m => m.ID == ID) .Select(m => new { m.ID, m.ISBN_ISSN });
} Jeg kan via debug se at min var indeholder det jeg ønsker men hvordan skal jeg returnere min var?
Nu kan det godt være jeg har misforstået hvad du gerne vil opnå... men:
Du leder efter en collection med samme primary-key?
Din var query - den kommer til at indeholde et object med to properties - hvordan hænger det sammen med din tblKatalog klasse - umiddelbart ville jeg tro, at du skulle instantiere nye tblKatalog instanser i din Select?
Du kan ikke returnere en anonym type fra en funktion. Den findes jo kun som 'var'
Du kan gøre 2 ting, enten bare returnere som den er, altså:
public static IEnumerable<tblKatalog> SelectWhereID(int ID) { DataClassesDataContext db = new DataClassesDataContext(); return db.tblKatalogs .Where(m => m.ID == ID) .Select(m => m);
} Forudsat et tblKatalog og tblKatalogs er samme type.
Du kan også. public static IEnumerable<tblKatalog> SelectWhereID(int ID) { DataClassesDataContext db = new DataClassesDataContext(); return db.tblKatalogs .Where(m => m.ID == ID) .Select(m => new tblKatalog() { prop1 = m.propvalue1, prop2 = m.propvalue2.... osv. } );
eller i ren query expression:
return db.tblKatalogs where m => m.ID == ID select new tblKatalog() { prop1 = m.propvalue1, prop2 = m.propvalue2.... osv. } );
op til dig :)
husk desuden at smide en using omkring din context alså.. using(var db = new DataClassesDataContext()) { return db.tblKatalogs .Where(m => m.ID == ID) .Select(m => m);
Tak for jeres besvarelser. Nu funker det næsten. Jeg prøver lige at forklare hvad jeg vil. Jeg har som sagt brugt Object relational designer. Herefter har jeg lavet en partial class med følgende:
public partial class tblKatalog { #region Select methods public static IEnumerable<tblKatalog> Select() { /// <summary> /// Returns unsorted list of entity /// </summary> DataClassesDataContext db = new DataClassesDataContext(); db.Log = new TraceWriter(); return db.tblKatalogs; }
Herefter har jeg lavet metoder til pageing cacheing som beskrevet i ASP.NET 3.5 Unleashed. Med jeres hjælp har jeg fået denne til at virke:
public static IEnumerable<tblKatalog> SelectWhereID(int ID) { DataClassesDataContext db = new DataClassesDataContext();
Men hvad gør jeg hvis jeg kun vil lave en Select på udvalgte columns? Har prøvet følgende: public static IEnumerable<tblKatalog> SelectShort() { DataClassesDataContext db = new DataClassesDataContext(); return db.tblKatalogs .Select(m => new tblKatalog() { ID = m.ID, Titel = m.Titel } );
} Og får følgende fejl: Explicit construction of entity type 'tblKatalog' in query is not allowed.
Herefter prøvede jeg med en using: public static IEnumerable<tblKatalog> SelectShort() { using(var db = new DataClassesDataContext()) return db.tblKatalogs .Select(m => new tblKatalog() { ID = m.ID, Titel = m.Titel } );
} Og fik følgende fejl: Cannot access a disposed object. Object name: 'DataContext accessed after Dispose.'.
Lav en ToList() :) , du tilgår data contexten efter den har været åbnet.
using(var db = new DataClassesDataContext()) return db.tblKatalogs .Select(m => new tblKatalog() { ID = m.ID, Titel = m.Titel } ).ToList();
Men i bund og grund er der jo ingen grund til at lave en metode, medmindre det naturligvis bare er for sjov eller fordi du skal følge nogle retningslinjer:
public IQueryable<tblKatalog> Query() { using(var db = new DataClassesDataContext()) { return db.tblKatalogs;
}
Og så i din kaldende metode:
var result = YourService.Query().Where(x => x.Id == 123).ToList();
Tak for dit svar janus. Har prøvet følgende men det virker stadig ikke. public static IEnumerable<tblKatalog> SelectShort() { using(var db = new DataClassesDataContext()) return db.tblKatalogs .Select(m => new tblKatalog() { ID = m.ID, Titel = m.Titel } ).ToList();
}
Giver denne fejl: Explicit construction of entity type 'tblKatalog' in query is not allowed
Så det er galt er måske at jeg forsøger at lave input seqencen om istedet for at lave en ny. Det burde jeg vel ikke med: "m => new" ??
Jeg er meget åben overfor en anden måde at gøre det på. Eneste krav er en adskillelse fra præsentationslaget. Det har jeg som sagt løst ved ar lave partial classes i App_Code
Hvis jeg lige laver et lille demoprojekt sp: using System.Collections.Generic; using System.Linq;
namespace ConsoleApplication2 { class Program { static void Main(string[] args) { var result = MyService.GetSome(); var resultAnotherWay = MyService.GetSomeOnAnotherWay("XXX");
var resultAnother = MyService.GetSomeMore().Where(m => m.CompanyName.StartsWith("A")).ToList();
} }
class MyService { public static IList<tEquity> GetSome() // funker fino :) { using (var context = new DataClasses1DataContext()) {
return context.tEquities.Select( m => new tEquity() { CompanyName = m.CompanyName, Currency = m.Currency } ).ToList();
}
}
public static IList<tEquity> GetSomeOnAnotherWay(string isin) // funker fino :) { using (var context = new DataClasses1DataContext()) {
Hej janus tak for din vedholdenhed. Det betyder meghet for mig at få løst dette problem hurtigst muligt.
Object relational designer er et grafisk værktøj i Visual Studio. Det er til os som ikke bygger alle vores entities og deres relations i hånden. Designeren generere en strongly typed DataContext class. Min database tabel tblKatalog bliver exposed af DataContext som en strongly typed property.
Designeren generere også en distinct class for hver databasetabel i dette tilfælde tblKatalog
Her er et uddrag af koden som genereres:
public System.Data.Linq.Table<tblKatalog> tblKatalogs { get { return this.GetTable<tblKatalog>(); } }
[Table(Name="dbo.tblKatalog")] public partial class tblKatalog : INotifyPropertyChanging, INotifyPropertyChanged {
private static PropertyChangingEventArgs emptyChangingEventArgs = new PropertyChangingEventArgs(String.Empty);
.... Herefter følger en masse metoder til relationerne til andre tabeller og datachanging events.
Og det er jo altsammen meget fint men ikke når jeg ikke kan arbejde med det og udvælge enkelte columns. Der er jo ingen grund til SELECT * når jeg kun skal bruge ID, ISBN og Titel. Jeg vil ikke have linq to sql kode i mine asp.net filer og har derfor oprettet partial classes og bruger objectdatasource til at repræsentere mine classes.
En alternativ løsning på problemet kunne være at jeg laver min egen datashape som kun indeholder columns jeg skal bruge.
Hej Igen Jeg sidder med Visual Studio 2008. Vil meget gerne have din demo. Gerne med eksempel på hvordan du vælger enkelte columns. Tak igen - jeg har været inde på din profil og kontakter dig.
Hej igen. Nu har jeg endelig fundet svaret på mit spørgsmål. Så jeg synes lige jeg ville give det her hvis der nu er andre som læser ASP.NET Unleashed og bøvler med det samme. Som med alle gode løsninger er det meget simpelt. Her er den originale kode: public static IEnumerable<tblKatalog> SelectWhereID(int ID) { DataClassesDataContext db = new DataClassesDataContext(); var query = db.tblKatalogs .Where(m => m.ID == ID) .Select(m => new { m.ID, m.ISBN_ISSN });
}
Eftersom en Select laver en nye anonym type er løsningen:
public static IEnumerable SelectWhereID(int ID) { DataClassesDataContext db = new DataClassesDataContext(); return db.tblKatalogs .Where(m => m.ID == ID) .Select(m => new { m.ID, m.ISBN_ISSN });
}
Det jeg ikke havde fattet var at eftersom typen er anonym skal der ikke være en <class> efter IEnumerable. Ak ja så simpelt kan det være. Endnu engang tak til dem som hjalp mig på vej
Synes godt om
Ny brugerNybegynder
Din løsning...
Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.