Link on datagrid DevExpress

Posts   
 
    
Posts: 13
Joined: 01-Nov-2010
# Posted on: 01-Nov-2010 12:29:03   

Hello,

I need help, I use DevExpress datagrid but I do not know how to link with the relationship 1: n confused I show you my code:

_entQuestionCollection = new EntityCollection<QuestionEntity>(new QuestionEntityFactory()); _entReponseCollection = new EntityCollection<ReponsesEntity>(new ReponsesEntityFactory());

       _entQuestionnaireColection = new EntityCollection<QuestionnaireEntity>(new QuestionnaireEntityFactory());

        using (DataAccessAdapter adapter = new DataAccessAdapter())
        {
            // load all customers and bind them to the combobox
            adapter.FetchEntityCollection(_entQuestionnaireColection, null, 0, new SortExpression(QuestionnaireFields.Titre | SortOperator.Ascending));
            _customersComboBox.DataSource = _entQuestionnaireColection;
            _customersComboBox.DisplayMember = "Titre";
            _customersComboBox.ValueMember = "IdQuestionnaire";
        }

I have a collection questionnaire linked to a comboBox

and the question of the questionnaire and these answers are linked to the datagrid, my problem is the answers

look after the code:

DataAccessAdapter adapter = new DataAccessAdapter();

        QuestionnaireEntity questionnaireEnt = (QuestionnaireEntity)_customersComboBox.SelectedItem;
        QuestionEntity qu = new QuestionEntity();


        if (questionnaireEnt.Question.Count > 0)
        {
            questionnaireEnt.Question.Clear();
        }

        _entQuestionCollection = GetQuestions(questionnaireEnt.IdQuestionnaire)
        _entReponseCollection = GetQuestionsRe(qu.IdQuestion)

IRelationPredicateBucket filter = new RelationPredicateBucket(); filter.PredicateExpression.Add(QuestionFields.IdQuestionnaire == questionnaireEnt.IdQuestionnaire); filter.Relations.Add(QuestionEntity.Relations.ReponsesEntityUsingIdQuestion);

        adapter.FetchEntityCollection(_entQuestionCollection, filter);
        adapter.FetchEntityCollection(_entReponseCollection, filter);

this.gridControl1.BeginUpdate();  
        this.bindingSourceQuestion.DataSource = null;

        this.bindingSourceQuestion.DataSource = _entQuestionCollection;
        gridControl1.DataSource = this.bindingSourceQuestion;

        CardView cardView1 = new CardView(gridControl1);
        gridControl1.LevelTree.Nodes.Add(" ?___________ ? ", cardView1);

        this.gridControl1.EndUpdate();

and methods:

    public static EntityCollection<QuestionEntity> GetQuestions(int? idQuestionnaire, IDataAccessAdapter adapter)
    {

        EntityCollection<QuestionEntity> questions = new EntityCollection<QuestionEntity>();

        // Recherche par Id Questionnaire
        IRelationPredicateBucket rel = new RelationPredicateBucket(QuestionFields.IdQuestionnaire == idQuestionnaire);

        rel.Relations.Add(QuestionEntity.Relations.QuestionnaireEntityUsingIdQuestionnaire);
        rel.Relations.Add(QuestionEntity.Relations.ReponsesEntityUsingIdQuestion);


        // Fetch questions
        adapter.FetchEntityCollection(questions, rel);

        return questions;
    }


    public static EntityCollection<ReponsesEntity> GetQuestionsRe(int? idQuestion)
    {
        using (IDataAccessAdapter adapter = new DataAccessAdapter(true))
            return GetQuestionsRe(idQuestion, adapter);
    }

    public static EntityCollection<ReponsesEntity> GetQuestionsRe(int? idQuestion, IDataAccessAdapter adapter)
    {

        EntityCollection<ReponsesEntity> questions = new EntityCollection<ReponsesEntity>();

        IRelationPredicateBucket rel = new RelationPredicateBucket(ReponsesFields.IdQuestion == idQuestion);

        rel.Relations.Add(ReponsesEntity.Relations.QuestionEntityUsingIdQuestion);


        adapter.FetchEntityCollection(questions, rel);

        return questions;
    }

thank you in advance for your help

confused

Posts: 13
Joined: 01-Nov-2010
# Posted on: 01-Nov-2010 12:57:48   

Explain me how to bind only with the relation 1:n question answer! wink Datagrid Devexpress

Walaa avatar
Walaa
Support Team
Posts: 14993
Joined: 21-Aug-2005
# Posted on: 01-Nov-2010 15:20:47   

I'm lost reading your code, sorry.

Would you please simplify your question and be more specific.

Posts: 13
Joined: 01-Nov-2010
# Posted on: 01-Nov-2010 18:06:36   

I actually like just know how to bind two tables with a relation 1;n dataGrid DevExpress ? with adapterconfused

daelmo avatar
daelmo
Support Team
Posts: 8245
Joined: 28-Nov-2005
# Posted on: 02-Nov-2010 05:02:40   

You have some some inconsistencies in your code. First lets fix your code:

/// This method bind the questions of the selected questionnaire. You should call this 
/// method in your _customersComboBox.SelectedChanged event handler.
public void BindQuestions()
{           
     // get the selected questionnaire
     QuestionnaireEntity questionnaireEnt =  (QuestionnaireEntity)_customersComboBox.SelectedItem;

     // get the questions of the questionnaire
     _entQuestionCollection = GetQuestions(questionnaireEnt.IdQuestionnaire);   


     // bind to your grid. Just do something like:
     _theQuestionsGrid.DataSource = _entQuestionCollection;
}

/// This method get the questions of the passed questionnaire
public static EntityCollection<QuestionEntity> GetQuestions(int? idQuestionnaire)
{
     EntityCollection<QuestionEntity> questions = new EntityCollection<QuestionEntity>();

     // just questions of the passed idQuestionnaire
     IRelationPredicateBucket quetionsFilter = new RelationPredicateBucket(QuestionFields.IdQuestionnaire == idQuestionnaire);

     using (DataAccessAdapter adapter = new DataAccessAdapter())
     {
          adapter.FetchEntityCollection(questions, quetionsFilter);
     }

     return questions;
}


/// This method give us the answers of the passed question      
public static EntityCollection<ReponsesEntity> GetQuestionsRe(int? idQuestion)
{
     EntityCollection<ReponsesEntity> responses = new EntityCollection<ReponsesEntity>();

     // just the answers of the selected question
     IRelationPredicateBucket responsesFilter = new RelationPredicateBucket(ReponsesFields.IdQuestion == idQuestion);

     using (IDataAccessAdapter adapter = new DataAccessAdapter(true))
     {  
          adapter.FetchEntityCollection(questions, rel);
     }
    
     return questions;
}

Ok, now your methods work. I left the comboBox code to you as it is good I think. With this code you:

  1. Bind the questionnaire comboBox. (not in above snippet)
  2. Handle the comboBoxChanged event to bind the questions grid (not in above snippet)
  3. Have method that retrieve the answers of a selected question.

The only thing you have to code now is when the user clicks one question. In that code you should retrieve the selected questionId and call the method that retrieve the answers. Now you should bind the result to the answers grid.

Hope helpful wink

David Elizondo | LLBLGen Support Team
Posts: 13
Joined: 01-Nov-2010
# Posted on: 02-Nov-2010 07:56:10   

Thank you for your code but I want that these two question and answer table and the same control datagrid because they are linked And the answer is in table when you select a tree from a sub gridview disappointed

Walaa avatar
Walaa
Support Team
Posts: 14993
Joined: 21-Aug-2005
# Posted on: 02-Nov-2010 08:44:53   

Please check the "Complex databinding example" solution posted on the download section of our website.

In there you shall find many master-detials scenarioes implemented.

Posts: 13
Joined: 01-Nov-2010
# Posted on: 03-Nov-2010 14:47:41   

I looked at the example but it does not work like the DevExpress DataGrid. I just need an example how to bind a datagrid with DevExpress relationship between two tables thank you in advance Sad

Walaa avatar
Walaa
Support Team
Posts: 14993
Joined: 21-Aug-2005
# Posted on: 03-Nov-2010 14:57:11   

It's not clear to me whether you want to bind master details to the same grid control or to different controls

Posts: 13
Joined: 01-Nov-2010
# Posted on: 03-Nov-2010 17:23:27   

I'm sorry for my English is not very good, what I want is:

I have one questionnaire questions and answers.

And I want to link the questions and answers to a datagrid knowing that a question has several answers. I looked at the example you offer me I do not understand my whole being LLBLGen beginner. linking 2 tables for old grid if I search a questionnaire I want the questions and answers bind the datagrid

daelmo avatar
daelmo
Support Team
Posts: 8245
Joined: 28-Nov-2005
# Posted on: 04-Nov-2010 05:06:33   

What we fail to see -I think- is what do you mean by "link two tables in the grid". Is that DevExpress a hierarchical grid? (For example, you can see the questions and if you click on question the grid expands that row with the answers of that question).

If so, you should fetch the questions with prefetched answers. Please take a look at PrefetchPaths.

David Elizondo | LLBLGen Support Team
Posts: 13
Joined: 01-Nov-2010
# Posted on: 04-Nov-2010 16:14:49   

yes it is a hierarchical grid but I do not see how preloading!

MTrinder
User
Posts: 1461
Joined: 08-Oct-2008
# Posted on: 04-Nov-2010 21:14:33   

1) Have you read the manual section about PreFetchPaths 2) Did you understand it...? simple_smile 3) Ignoring the grid for the moment, can you fetch from the database a collection of questions, each with their related answers...?

Let us know how you get on.

Matt

Posts: 13
Joined: 01-Nov-2010
# Posted on: 04-Nov-2010 23:10:53   

yes I looked and I manage to recover these questions and answers how to do next and how to retrieve the name of the relation? confused

daelmo avatar
daelmo
Support Team
Posts: 8245
Joined: 28-Nov-2005
# Posted on: 05-Nov-2010 05:43:26   

What do you have so far? and Why do you want to know the name of the relation?

David Elizondo | LLBLGen Support Team
Posts: 13
Joined: 01-Nov-2010
# Posted on: 05-Nov-2010 10:56:29   
 public void BindQuestions()
        {
            // get the selected questionnaire
            QuestionnaireEntity questionnaireEnt = (QuestionnaireEntity)_customersComboBox.SelectedItem;

            // get the questions of the questionnaire
            _entQuestionCollection = GetQuestions(questionnaireEnt.IdQuestionnaire);

            // bind to your grid. Just do something like:
            this.gridControl1.DataSource = _entQuestionCollection;

        }

         //This method get the questions of the passed questionnaire
        public static EntityCollection<QuestionEntity> GetQuestions(int? idQuestionnaire)
        {

            EntityCollection<QuestionEntity> questions = new EntityCollection<QuestionEntity>();

            // just questions of the passed idQuestionnaire
            IRelationPredicateBucket quetionsFilter = new RelationPredicateBucket(QuestionFields.IdQuestionnaire == idQuestionnaire);

            using (DataAccessAdapter adapter = new DataAccessAdapter())
            {
                adapter.FetchEntityCollection(questions, quetionsFilter);
            }

            return questions;
        }

        private void gridView1_RowCellClick(object sender, RowCellClickEventArgs e)
        {
            
            EntityCollection reponseCollection = new EntityCollection(new ReponsesEntityFactory());

            IPrefetchPath2 prefetchPath = new PrefetchPath2((int)EntityType.ReponsesEntity);
            prefetchPath.Add(ReponsesEntity.PrefetchPathQuestion);

            IRelationPredicateBucket filter = new RelationPredicateBucket();

            filter.PredicateExpression.Add(ReponsesFields.IdQuestion == e.CellValue);

            DataAccessAdapter adapter = new DataAccessAdapter();

            adapter.FetchEntityCollection(reponseCollection, filter, prefetchPath);

            CardView cardView1 = new CardView(gridControl1);
        gridControl1.LevelTree.Nodes.Add("RelationName", cardView1);

}

I get the ID of the item when the user thanks to the event: gridView1_RowCellClick (object sender, RowCellClickEventArgs e)

"Filter.PredicateExpression.Add (ReponsesFields.IdQuestion == e.CellValue);"

Is it good for you? Now how do I bind the answers?

Walaa avatar
Walaa
Support Team
Posts: 14993
Joined: 21-Aug-2005
# Posted on: 05-Nov-2010 12:35:19   

I guess you mean by Answers a collleciton of ResponseEntity, right?

As far as I can see, your code fetches a collection of QuestionEntity according to the Id of the QuestionnaireEntity selected from the customersComboBox. (side note: I think you need to change the name of the comboBox to better reflect what it holds).

Then you bind these Questions to a GridView.

Then on RowCellClick you want to fetch the Answers (ResponseEntity) for each question.

Since you need to bind Questions and their Responses to the same Grid (Hierarchical grid). We have been telling you that you should fetch the Questions and The responces using PrefecthPaths.

You are not doing this, but you fetch the Responses alone when selecting a row from the Grid, and you use a prefecthPath then to re-fetch the Question in hand, which is completely needless.

Don't use RowCellClick, and instead use the following:

        public static EntityCollection<QuestionEntity> GetQuestions(int? idQuestionnaire)
        {

            EntityCollection<QuestionEntity> questions = new EntityCollection<QuestionEntity>();

            // just questions of the passed idQuestionnaire
            IRelationPredicateBucket quetionsFilter = new RelationPredicateBucket(QuestionFields.IdQuestionnaire == idQuestionnaire);

            IPrefetchPath2 prefetchPath = new PrefetchPath2((int)EntityType.QuestionEntity);
            prefetchPath.Add(QuestionEntity.PrefetchPathResponses);

            using (DataAccessAdapter adapter = new DataAccessAdapter())
            {
                adapter.FetchEntityCollection(questions, quetionsFilter, prefecthPath);
            }

            return questions;
        }

This is how you fetch Questions plus their Responses. Now if you want to bind these to some Hierarchical Grid, I'd recommend you place your comment on the Forums of that Grid Vendor, be it DevExpress or anything else.

Posts: 13
Joined: 01-Nov-2010
# Posted on: 05-Nov-2010 12:57:03   

Normal questions that I seek as I select a questionnaire to see these issues. Thank you for your help, but you have no idea to bind the grid? correct these issues but how to bind the answers? Could you explain how to retrieve the name of the relationship

frowning

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39861
Joined: 17-Aug-2003
# Posted on: 05-Nov-2010 13:19:28   

jeanflo2302 wrote:

Normal questions that I seek as I select a questionnaire to see these issues. Thank you for your help, but you have no idea to bind the grid? correct these issues but how to bind the answers? Could you explain how to retrieve the name of the relationship frowning

You mean, the name of the field mapped onto the relationship, e.g. 'Orders' in Customer.Orders ?

I think the reason this isn't solved yet is because we think you mean A, help you with that, but you mean B and don't understand why we want to help with A. simple_smile So let's get back to what the problem really is, and go from there.

What I think you are trying to do is that when someone clicks open a card view, the related information is loaded, am I right in that? Adapter doesnt support lazy loading, so you have to fetch the data INTO the data already bound.

So say you have a list of customers bound to the grid and when I click open a customer row, the ORDERS of that customer have to be loaded and shown IN the grid as a set of rows below it, correct? (in your example, it is questions, and you click open a question and all answers have to be loaded, correct?)

What we suggested was to load all related data BEFORE you bind the customers to the grid, or in your case, the questions. So with a prefetch path on Questions, to fetch the additional answers, you bind questions to the grid and specify in the devexpress grid that you want to view 'related data' (that's a devexpress topic, please look it up in their manual).

If you want to fetch data on the fly so not BEFOREHAND, you should simply do: - find the Question Entity instance of the current row - fetch the Answers collection of that entity: adapter.FetchEntityCollection(questionEntity.Answers, questionEntity.GetRelationInfoAnswers());

but beware: it has to be setup properly in the devexpress grid: show related info. This can be a cumbersome topic on its own, as I too found showing related data in a devexpress grid problematic. But I just wanted to let you know that the llblgen pro part of the puzzle you're facing has been answered above, at least I hope I now have given the last piece of it simple_smile

Frans Bouma | Lead developer LLBLGen Pro
Posts: 13
Joined: 01-Nov-2010
# Posted on: 05-Nov-2010 13:54:29   

everything you say is exactly what I want to do! But I do not find a example for my question in the doc DevExpress it does not use LLBLGen. I already try to do what you explain, but if you have an idea for the association?

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39861
Joined: 17-Aug-2003
# Posted on: 05-Nov-2010 13:57:40   

jeanflo2302 wrote:

everything you say is exactly what I want to do! But I do not find a example for my question in the doc DevExpress it does not use LLBLGen. I already try to do what you explain, but if you have an idea for the association?

I do recall having to search for that too, but can't find it immediately. I'll see what I can dig up for you.

Frans Bouma | Lead developer LLBLGen Pro
Posts: 13
Joined: 01-Nov-2010
# Posted on: 05-Nov-2010 14:08:32   

c'est super par ce que je rame vraiment et je fais des recherche de mon côté merci encore wink

it's great for what I train and I really am doing some research on my side thank you againwink

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39861
Joined: 17-Aug-2003
# Posted on: 05-Nov-2010 14:36:30   

Ok, turned out to be easy.


namespace Tester
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        protected override void OnLoad(EventArgs e)
        {
            base.OnLoad(e);
            var customers = new EntityCollection<CustomerEntity>();
            using(var adapter = new DataAccessAdapter())
            {
                adapter.FetchEntityCollection(customers, null);
            }
            bindingSource1.DataSource = customers;
        }


        private void gridView1_MasterRowExpanding(object sender, MasterRowCanExpandEventArgs e)
        {
            var customer = (CustomerEntity)gridView1.GetRow(e.RowHandle);
            if(customer == null)
            {
                return;
            }
            using(var adapter = new DataAccessAdapter())
            {
                adapter.FetchEntityCollection(customer.Orders, customer.GetRelationInfoOrders());
            }
        }
    }
}

grid: just a default grid with a datasource bound to it. This will give the columns of the entity set as datasource of the datasource (here: customer)

It's important to look into 'Master-Detail' in the devexpress' grid docs. Go to: Windows forms components -> XtraGrid -> Fundamentals -> Views and Levels and Windows forms components -> XtraGrid -> Concepts -> Master-detail relationships (several topics).

If you have problems with the above code please also ask devexpress, as they're the ones which should give you support on devexpress' grid material wink

I'll zip the stuff and attach it.

(edit) attached. DXGrid 10.1, vs.net 2010. It's llblgen 3, but the code is easy to read (Tester project, form1.cs).

Frans Bouma | Lead developer LLBLGen Pro