2010-10-24 24 views
4

Si j'ai une classe comme les suivantes:Entity Framework 4: comment coder la projection dans un type de classe?

public class Customer { 
    public int id {get;set;} 
    public string name {get;set;} 
    public string line1 {get;set;} 
    public string line2 {get;set;} 
    public string line3 {get;set;} 
    public string line4 {get;set;} 
} 

Et je veux seulement sélectionner les valeurs d'identité et le nom, laissant le reste nul.

var myCustomerList = DC.Customer.Select( 
        p => new Customer { id = p.id, name = p.name }); 

je reçois l'erreur suivante:

The entity or complex type 'MyModel.Customer' cannot 
be constructed in a LINQ to Entities query. 

Sinon, comment feriez-vous? Suis-je obligé de spécifier tous les champs de la classe?

+0

Avez-vous trouvé une bonne solution à votre problème? – Learner

Répondre

2

Essayez ceci:

var myCustomerList = from c in DC.Customer 
        select new { id = p.id, name = p.name }; 

Le ci-dessus créent un Anonymous Type.

Application pratique:

"var myCustomerList" < - Type Anonyme.

Un type anonyme avec deux propriétés "id" et "name". De plus, "var" vous permet de créer une variable locale implicitement typée. Cela signifie:

a) Vous n'avez pas eu à déclarer/écrire une structure de classe pour contenir un type avec seulement ces deux propriétés;

b) Vous n'avez pas besoin de le faire - vous pouvez changer la structure de la requête ci-dessus, et "ça marche".

+0

Dites que vous voulez retourner l'objet fortement typé où le reste des champs sont nuls? J'ai utilisé votre conseil, puis bouclé à travers l'objet anonyme alimentant une nouvelle liste afin que mon référentiel n'ait pas besoin d'une tonne de classes ViewModel définies. –

+0

J'ai fait une boucle dans les enregistrements parce que je ne suis pas toujours sûr combien de champs seront dans le modèle de domaine (s'ils ajoutent plus). –

0

Une autre option est de créer un type CustomerInfo:

public class CustomerInfo 
{ 
    public int Id { get; set;} 
    public string Name { get; set; } 
} 

Vous ne pouvez pas mapper deux types directement à la même table EF mais vous pouvez facilement créer une vue pour votre type d'information et la carte à cette :

CREATE VIEW vwCustomerInfo AS SELECT Id, Name FROM Customer 

vous associez ensuite votre type de CustomerInfo à votre vue:

public class CustomerInfoMap : EntityConfiguration<CustomerInfo> 
{ 
    public CustomerInfoMap() 
    { 
    .ToTable("vwCustomerInfo"); 
    } 
} 

A Side- Effet de ceci est que EF récupérera seulement les colonnes dans la vue en interrogeant votre base de données. Lors de la récupération d'un CustomerInfo par id vous obtiendrez SQL comme ceci:

SELECT Id, Name FROM vwCustomers WHERE id = 1

De plus, tant que votre vue est actualisable, vous pouvez mettre à jour votre type de CustomerInfo de EF et de la table sous-jacente sera mis à jour.