IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Framework .NET Discussion :

Linq, OrderBy sur propriété hors base de donnée


Sujet :

Framework .NET

  1. #1
    Membre émérite Avatar de neptune
    Profil pro
    Inscrit en
    Novembre 2003
    Messages
    835
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Novembre 2003
    Messages : 835
    Par défaut Linq, OrderBy sur propriété hors base de donnée
    Bonjour à tous,

    J'ai une classe mappée à partir d'une table. Je lui ai ajouté une propriété sur laquelle j'aimerais faire un tri. Cette propriété est le résultat d'un calcul sur des propriétés mappées sur la table. Evidement, Linq refuse ce tri.

    Il doit pourtant bien y avoir un moyen de contourner cette limitation, j'en appelle donc au plus versé que moi en Linq. Quels sont les pistes à explorer pour y arriver?

    Merci d'avance!

  2. #2
    Membre éprouvé Avatar de anthyme
    Homme Profil pro
    Inscrit en
    Mars 2004
    Messages
    1 559
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Mars 2004
    Messages : 1 559
    Par défaut
    en gros du calcul métier pour déterminer l'ordre du tri ?

    bin tu peux faire ta requete linq to sql sans orderby puis trier avec linq to object dans ta couche business

  3. #3
    Membre émérite Avatar de neptune
    Profil pro
    Inscrit en
    Novembre 2003
    Messages
    835
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Novembre 2003
    Messages : 835
    Par défaut
    Hmm, je vais te donner plus d'explications :-)

    J'ai un GridView, avec paging et tri. Son datasource est un objectdatasource, qui autorise le paging et le tri, avec la méthode Count qui va bien et une méthode Select qui pointe sur mon Controller.

    Le GridView affiche des colonnes "data" et "business" et je veux pouvoir trier autant sur l'une que sur l'autre. J'utilise Dynamic Linq qui permet de donner la colonne sur laquelle je trie via une string.

    Je voudrais garder cette facilité. Je pense que c'est au sein de ma class business que je devrais pouvoir lui indiquer (avec des attributs, ou une Expression, que sais-je) comment connaitre la bonne façon de faire le tri.

    Je dump les parties intéressantes (cfr. image jointe pour le dbml).

    Default.aspx
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    <asp:GridView ID="ForumGridView" runat="server" DataSourceID="ForumObjectDataSource" AutoGenerateColumns="false" AllowSorting="true">
    	<Columns>
    		<asp:BoundField DataField="Name" HeaderText="Name" SortExpression="Name" />
    		<asp:BoundField DataField="NumberOfTopic" HeaderText="NumberOfTopic" SortExpression="NumberOfTopic" />
    		<asp:BoundField DataField="NumberOfMessage" HeaderText="NumberOfMessage" SortExpression="NumberOfMessage" />
    		<asp:BoundField DataField="LastMessageDate" HeaderText="LastMessageDate" SortExpression="LastMessageDate" />
    		<asp:BoundField DataField="LastMessageTitle" HeaderText="LastMessageTitle" SortExpression="LastMessageTitle" />
    	</Columns>
    </asp:GridView>
     
    <asp:ObjectDataSource ID="ForumObjectDataSource" runat="server" 
    	OldValuesParameterFormatString="original_{0}" SelectMethod="GetAvailableForumFromSection" 
    	TypeName="MyForum.Business.Controllers.ForumController" 
    	SortParameterName="sortExpression">
    	<SelectParameters>
    		<asp:ControlParameter ControlID="SectionIdHiddenField" Name="sectionId" Type="Int32" />
    	</SelectParameters>
    </asp:ObjectDataSource>
    Forum.cs
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    public partial class Forum
    {
    	private Message LastMessage
    	{
    		get { return Messages.OrderBy(m => m.CreationDate).FirstOrDefault(); }
    	}
     
    	public int NumberOfTopic
    	{
    		get { return Messages.Where(m => m.Topic == null).Count(); }
    	}
     
    	public int NumberOfMessage
    	{
    		get { return Messages.Count(); }
    	}
     
    	public DateTime? LastMessageDate
    	{
    		get
    		{
    			Message m = LastMessage;
     
    			if (m == null)
    			{
    				return null;
    			}
     
    			return m.CreationDate;
    		}
    	}
     
    	public string LastMessageTitle
    	{
    		get
    		{
    			Message m = LastMessage;
     
    			if (m == null)
    			{
    				return null;
    			}
     
    			return m.Title;
    		}
    	}
    }
    ForumController.cs
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
     public class ForumController : GenericController<Forum, MyForumDataContext>
    {
    	public static IQueryable<Forum> GetAvailableForumFromSection(int sectionId)
    	{
    		var results = SelectAll().Where(f => f.SectionId == sectionId);
     
    		return results;
    	}
     
    	public static IQueryable<Forum> GetAvailableForumFromSection(int sectionId, string sortExpression)
    	{
    		if (String.IsNullOrEmpty(sortExpression))
    		{
    			return GetAvailableForumFromSection(sectionId);
    		}
     
    		return GetAvailableForumFromSection(sectionId).OrderBy(sortExpression);
    	}
    }
    GenericController.cs
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    public abstract class GenericController<TEntity, TDataContext>
            where TDataContext : DataContext
            where TEntity : class
    {
    	protected static Table<TEntity> EntityTable
    	{
    		get { return DataContext.GetTable<TEntity>(); }
    	}
     
    	public static IQueryable<TEntity> SelectAll()
    	{
    		return EntityTable;
    	}
    }
    Images attachées Images attachées  

  4. #4
    Membre éprouvé Avatar de anthyme
    Homme Profil pro
    Inscrit en
    Mars 2004
    Messages
    1 559
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Mars 2004
    Messages : 1 559
    Par défaut
    Je suis pas sur d'avoir tout compris mais il me semble que pour ces utilisations en linq to sql il est préconisé d'utiliser des expressions tree

  5. #5
    Membre émérite Avatar de neptune
    Profil pro
    Inscrit en
    Novembre 2003
    Messages
    835
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Novembre 2003
    Messages : 835
    Par défaut
    Citation Envoyé par anthyme Voir le message
    Je suis pas sur d'avoir tout compris mais il me semble que pour ces utilisations en linq to sql il est préconisé d'utiliser des expressions tree
    En gros, je veux pouvoir trier sur n'importe quelle propriété de mon business object, avec une méthod générique, qui prend en argument la propriété sur laquelle je veux opérer mon tri.

    Je jette un oeil sur les expressions trees, et je pense que c'est ce dont j'ai besoin. Je reviendrai sur ce fil si la solution est trouvée.

    Merci.

  6. #6
    Membre éprouvé Avatar de anthyme
    Homme Profil pro
    Inscrit en
    Mars 2004
    Messages
    1 559
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Mars 2004
    Messages : 1 559
    Par défaut
    Citation Envoyé par neptune Voir le message
    En gros, je veux pouvoir trier sur n'importe quelle propriété de mon business object, avec une méthod générique, qui prend en argument la propriété sur laquelle je veux opérer mon tri.

    Je jette un oeil sur les expressions trees, et je pense que c'est ce dont j'ai besoin. Je reviendrai sur ce fil si la solution est trouvée.

    Merci.
    oui oui c'est bien le truc qu'il te faut

  7. #7
    Membre émérite Avatar de neptune
    Profil pro
    Inscrit en
    Novembre 2003
    Messages
    835
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Novembre 2003
    Messages : 835
    Par défaut
    Citation Envoyé par anthyme Voir le message
    oui oui c'est bien le truc qu'il te faut
    Ca m'a l'air bien complexe en tout cas... L'idée est que j'aimerais pouvoir binder sur la propriété business pour la présenter et utiliser la même pour trier. Va falloir trouver une astuce...

  8. #8
    Membre émérite Avatar de neptune
    Profil pro
    Inscrit en
    Novembre 2003
    Messages
    835
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Novembre 2003
    Messages : 835
    Par défaut
    Bon, j'ai résolu mon problème d'une façon différente. Je créé un type anonyme qui reprend les propriétés sur lesquelles on peut trier.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    public static IQueryable GetAvailableForumFromSection(int sectionId)
            {
                //var results = SelectAll().Where(f => f.SectionId == sectionId);
     
                var results = from f in DataContext.Forums
                              select new
                              {
                                  f.Name,
                                  NumberOfTopic = f.Messages.Where(m => m.Topic == null).Count(),
                                  NumberOfMessage = f.Messages.Count(),
                                  LastMessageDate = "",
                                  LastMessageTitle = ""
                              };
     
                return results;
            }

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 4
    Dernier message: 17/01/2012, 04h50
  2. aide sur conexion au base de donne oracle
    Par aymengomez dans le forum VB 6 et antérieur
    Réponses: 2
    Dernier message: 26/04/2007, 11h31
  3. Réponses: 5
    Dernier message: 16/02/2007, 09h44
  4. Réponses: 4
    Dernier message: 14/02/2007, 17h53
  5. statistiques sur les appels à base de données
    Par garfieldcut dans le forum JDBC
    Réponses: 2
    Dernier message: 27/12/2006, 10h52

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo