428 Stimmen

Die Entität kann nicht in einer LINQ to Entities-Abfrage erstellt werden

Es gibt einen Entitätstyp namens Product die vom Entity Framework generiert wird. Ich habe diese Abfrage geschrieben

public IQueryable<Product> GetProducts(int categoryID)
{
    return from p in db.Products
           where p.CategoryID== categoryID
           select new Product { Name = p.Name};
}

Der folgende Code führt zu folgendem Fehler:

"Die Entität oder der komplexe Typ Shop.Product kann nicht in einem LINQ to Entities-Abfrage erstellt werden"

var products = productRepository.GetProducts(1).Tolist();

Aber wenn ich die select p anstelle von select new Product { Name = p.Name}; es funktioniert richtig.

Wie kann ich einen benutzerdefinierten Auswahlbereich erstellen?

0voto

Sterling Diaz Punkte 3548

In vielen Fällen ist die Umwandlung nicht erforderlich. Überlegen Sie, aus welchem Grund Sie den starken Typ Liste benötigen, und prüfen Sie, ob Sie die Daten z. B. nur in einem Webdienst oder zur Anzeige benötigen. Der Typ spielt dabei keine Rolle. Sie müssen nur wissen, wie Sie die Daten lesen und überprüfen können, ob sie mit den Eigenschaften des von Ihnen definierten anonymen Typs identisch sind. Das ist das optimale Szenario, denn man braucht nicht alle Felder einer Entität, und das ist der Grund, warum es anonyme Typen gibt.

Eine einfache Möglichkeit ist dies:

IEnumerable<object> list = dataContext.Table.Select(e => new { MyRequiredField = e.MyRequiredField}).AsEnumerable();

0voto

vapcguy Punkte 6445

Sie können nicht auf Product zurückgreifen, da dies Ihre Tabelle ist, die Sie abfragen. Sie brauchen eine anonyme Funktion, dann können Sie sie zu einem ViewModel hinzufügen, und jedes ViewModel zu einer List<MyViewModel> und geben diese zurück. Es ist eine kleine Abschweifung, aber ich füge Vorbehalte über den Umgang mit nullable Daten, weil diese sind ein Schmerz in den Hintern zu behandeln, nur für den Fall, dass Sie einige haben. Dies ist, wie ich es behandelt.

Hoffentlich haben Sie eine ProductViewModel :

public class ProductViewModel
{
    [Key]
    public string ID { get; set; }
    public string Name { get; set; }
}

Ich habe Dependency Injection/Repository Framework, wo ich eine Funktion aufrufen, um meine Daten zu greifen. Mit Ihrem Beitrag als Beispiel, in Ihrem Controller-Funktion aufrufen, würde es wie folgt aussehen:

int categoryID = 1;
var prods = repository.GetProducts(categoryID);

In der Repository-Klasse:

public IEnumerable<ProductViewModel> GetProducts(int categoryID)
{
   List<ProductViewModel> lstPVM = new List<ProductViewModel>();

   var anonymousObjResult = from p in db.Products
                            where p.CategoryID == categoryID 
                            select new
                            {
                                CatID = p.CategoryID,
                                Name = p.Name
                            };

        // NOTE: If you have any dates that are nullable and null, you'll need to
        // take care of that:  ClosedDate = (DateTime?)p.ClosedDate ?? DateTime.Now

        // If you want a particular date, you have to define a DateTime variable,
        // assign your value to it, then replace DateTime.Now with that variable. You
        // cannot call a DateTime.Parse there, unfortunately. 
        // Using 
        //    new Date("1","1","1800"); 
        // works, though. (I add a particular date so I can edit it out later.)

        // I do this foreach below so I can return a List<ProductViewModel>. 
        // You could do: return anonymousObjResult.ToList(); here
        // but it's not as clean and is an anonymous type instead of defined
        // by a ViewModel where you can control the individual field types

        foreach (var a in anonymousObjResult)
        {                
            ProductViewModel pvm = new ProductViewModel();
            pvm.ID = a.CatID;  
            pvm.Name = a.Name;
            lstPVM.Add(rvm);
        }

        // Obviously you will just have ONE item there, but I built it 
        // like this so you could bring back the whole table, if you wanted
        // to remove your Where clause, above.

        return lstPVM;
    }

Zurück in den Controller, Sie tun:

 List<ProductViewModel> lstProd = new List<ProductViewModel>();

 if (prods != null) 
 {
    // For setting the dates back to nulls, I'm looking for this value:
    // DateTime stdDate = DateTime.Parse("01/01/1800");

    foreach (var a in prods)
    {
        ProductViewModel o_prod = new ReportViewModel();
        o_prod.ID = a.ID;
        o_prod.Name = a.Name;
       // o_prod.ClosedDate = a.ClosedDate == stdDate ? null : a.ClosedDate;
        lstProd.Add(o_prod);
    }
}
return View(lstProd);  // use this in your View as:   @model IEnumerable<ProductViewModel>

-1voto

HamidReza Punkte 1352

Nur AsEnumerable() hinzufügen:

public IQueryable<Product> GetProducts(int categoryID)
{
    return from p in db.Products.AsEnumerable()
           where p.CategoryID== categoryID
           select new Product { Name = p.Name};
}

-2voto

HamidReza Punkte 1352

Können Sie AsEnumerable zu Ihrer Sammlung wie folgt hinzufügen:

public IQueryable<Product> GetProducts(int categoryID)
{
    return from p in db.Products.AsEnumerable()
           where p.CategoryID== categoryID
           select new Product { Name = p.Name};
}

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X