2017-06-27 4 views
0

je un objetÉcrire des fonctions à utiliser dans C# déclaration LINQ

public class Product{ 
     public int Id { get; set; } 
     public double Cost { get; set; } 
     public DateTime DatePurchased { get; set; } 
     public string Name { get; set; } 
     public string Barcode { get; set; } 
     public string Category { get; set; } 
} 

J'ai aussi une fonction public void TotalProductDiscountHistory(DateTime datePurchased, double cost) qui fait des mathématiques complexes et renvoient les valeurs de réduction du jour où il a été acheté à ce jour. Je voudrais essentiellement pouvoir appeler cette fonction dans ma requête pour retourner la somme de tous les possibles pour tous les produits comme montré ci-dessous.

var query = db.Products.where(x => x.clientId == clientId) 
.GroupBy(c => c.Category).Select(a => new { 
Category = a.Category, 
Cost = a.Sum(u => u.Cost), 
TotalDiscounts = a.Sum(TotalProductDiscountHistory(a.DatePurchased, 
a.Cost)) 
}); 

Mes questions est de savoir comment puis-je obtenir ceci ou plutôt comment puis-je créer une fonction afin que je puisse l'appeler dans une instruction de requête LINQ, transmettre des valeurs et renvoyer un résultat.

+0

Avez-vous essayé la façon dont vous l'avez fait et il a échoué? –

+5

Votre fonction renvoie 'void' et ne peut donc pas être utilisée dans' Sum' – Hintham

+1

'J'ai aussi une fonction public void TotalProductDiscountHistory (DateTime dateAchat, double coût) qui effectue des calculs complexes et retourne les valeurs de réduction du jour où elle a été achetée date.' - Comment avez-vous un 'void'" valeurs de réduction de retour "? Si elle retourne, elle devrait retourner int/double/IEnumerable /... – Nsevens

Répondre

0

Votre problème principal est que l'EF tente de convertir la requête LINQ en SQL. Comme il y a un équivalent SQL de votre fonction, il faut vraiment extraire les données nécessaires pour ce calcul, et le faire après la requête SQL, dans le code.

Linq2SQL était excellent pour la gestion automatique. EF (même après 6 versions), pas tellement.

Donc, nous allons devoir le faire manuellement:

public double TotalProductDiscountHistory(DateTime datePurchased, double cost) {...} 

class CategoryTotals 
{ 
    public int Category {get; set;} 
    public double Cost {get; set;} 
    public double TotalDiscounts {get; set;} 
} 

var query = from p in db.Products 
      where P.clientId == clientId 
      group p by p.Category; 


var totals = new List<CategoryTotals>(); 
foreach(var grp in query) 
{ 
    var ct = new CategoryTotals 
      { 
       Category =grp.Category, 
       Cost = grp.Sum(u => u.Cost), 
       TotalDiscounts = grp.Sum(u=> 
         TotalProductDiscountHistory(u.DatePurchased, u.Cost)) 
      }; 
    totals.add(ct); 
}