Results 1 to 7 of 7

Thread: Setting Combobox DataSources using Entity Framework

  1. #1

    Thread Starter
    Fanatic Member
    Join Date
    Mar 2013
    Location
    Minneapolis, MN
    Posts
    531

    Setting Combobox DataSources using Entity Framework

    Hello:

    Why wont this third item work? The first two work great!! I have several combo boxes to define.

    Thanks for the help!

    Code:
            private void loadJobs()
            {
                using (var db = new ResourcePlanningEntities())
                {
                    dgvJobs.DataSource = db.Jobs.ToList();
                    cboCustomer.DataSource = db.Jobs.Select(a => a.Customer).Distinct().ToList();
    
                    // Why wont this third item work?  The first two work great!!  I have several combo boxes to define.  
                    cboCity.DataSource = db.Jobs.Select(b => b.City).Distinct().ToList();
    
                    // Or this...
                    cboCity.DataSource = db.Jobs.Select(a => a.City).Where(a => a.Customer == cboCustomer.ValueMember).Distinct().ToList();
    
    
    
                }
    
            }

  2. #2
    Super Moderator jmcilhinney's Avatar
    Join Date
    May 2005
    Location
    Sydney, Australia
    Posts
    110,299

    Re: Setting Combobox DataSources using Entity Framework

    OMG! Are we actually here again? I've already told you that you need to call Where first. In the third case you aren't calling Where at all, so you're obviously not calling it first. In the fourth case, you are calling Select before Where, so obviously Select is called first and Where is called second. It boggles my mind that you're still doing the same thing wrong weeks later. By calling Select first you are creating a list of City values, which are Strings if I recall correctly. You are then trying to filter that list of Strings by their Customer property, but since when does a String have a Customer property? It's a Job that has a Customer property, which is why you need to call Where on the list of Jobs that you had before you called Select. I've already explained all this more than once but even if I hadn't, I have told you to call Where first so why are you still not calling it first?

  3. #3

    Thread Starter
    Fanatic Member
    Join Date
    Mar 2013
    Location
    Minneapolis, MN
    Posts
    531

    Re: Setting Combobox DataSources using Entity Framework

    I work on multiple projects. I have done nothing with this part since the last question.

    Why do the first two lines work? Obviously, the second is not supposed to.

    I am totally guessing on syntax here.

    In the VB world, I would just use a select to set the recordset. Surely, these is something similar in Entity Framework.

    This is a fundamental understanding I do not have, and you and I are not connecting in a healthy way. I was not expecting you to chime in, perhaps someone else might. So, in response to OMG, are we here again, I'm sorry I asked.

    Perhaps there is a topic I am familiar with that you are not, that I can answer for you, and explain in some form using an analogy or an understanding between topics, such as, this in VB.NET is equivalent to this in Entity Framework or SolidWorks extrusions vs Inventor extrusions in 3D modeling??

    I thought I could call fields like str string = table.field;, which is really what I am after here. I do believe I have been clear that I have not used Entity Framework before.

    Sorry for the trouble. I did not even realize this was the same forum, as I have avoided the other one on this topic so as not to inconvenience you. And I certainly do not expect you to go beyond the scope of the forum with me.
    Last edited by ssabc; Jan 14th, 2018 at 11:04 PM.

  4. #4
    Super Moderator jmcilhinney's Avatar
    Join Date
    May 2005
    Location
    Sydney, Australia
    Posts
    110,299

    Re: Setting Combobox DataSources using Entity Framework

    Before we go any further, please don't describe a problem as just "it doesn't work". That is far too vague to be particularly useful in many cases. You might have code that won't compile, or code that compiles but crashes when run, or code that runs but behaves in a manner other than expected. Any of those three cases could be described as not working but they each require a different approach to fix. Also, there's a great deal of variation within each group too. If there's a compilation or run-time error then give us the exact error message and (although not an issue in this case) tell us exactly where it occurs. If the issue is unexpected behaviour then tell us exactly what behaviour was expected and what occurred.

    With this problem specifically, my issue is that you seem not to be understanding simple English. I have said more than once that you need to call Where first. Do you not know what "first" or "before" means? This is your code:
    csharp Code:
    1. cboCity.DataSource = db.Jobs.Select(a => a.City)
    2.                             .Where(a => a.Customer == cboCustomer.ValueMember)
    3.                             .Distinct()
    4.                             .ToList();
    In that case, you're calling Select first and Where second. I don't understand how it's confusing to you when I tell you to call Where first.
    csharp Code:
    1. cboCity.DataSource = db.Jobs.Where(a => a.Customer == cboCustomer.ValueMember)
    2.                             .Select(a => a.City)
    3.                             .Distinct()
    4.                             .ToList();
    Now that is calling Where first and Select second. What exactly is confusing about that? When someone posts here asking a programming question, I don;t think that it's unreasonable to expect them to understand the basics of programming in their chosen language, e.g. if I say "set property X" or "call method Y" then I don't expect to have to explain what a property or a method is. I certainly don't expect to have to explain what common words like "first" mean.

    As to why some of the code works and some doesn't, the parts that work have nothing wrong with them while the parts that don't work do have something wrong. I've explained what was wrong with the last line but let's look at each one more closely.
    csharp Code:
    1. dgvJobs.DataSource = db.Jobs.ToList();
    That line takes all the Job items in your EF context and puts them in a List<Job> and binds that to a DataGridView. That means that the grid will have a column for each property of the Job type. Seems fairly simple.
    csharp Code:
    1. cboCustomer.DataSource = db.Jobs.Select(a => a.Customer).Distinct().ToList();
    This line takes all the Job items in your EF context and gets the Customer property value from each one, then removes duplicates and then puts the remaining items in a List<T>. I'm not sure what the Customer property of a Job actually contains because you haven't told us. My guess is that it is a complex type, i.e. corresponds to another table in the database. In that case, your ComboBox will contain a List<Customer> and the user will see one property value of those items based on how you set the DisplayMember of that ComboBox.
    csharp Code:
    1. cboCity.DataSource = db.Jobs.Select(b => b.City).Distinct().ToList();
    You say that this line doesn't work but I don't know what that means because haven't told us. I don't know whether it fails to compile or throws an exception or simply displays unexpected data. I can only guess based on what I think your model may be.

    On the face of it, that line takes all the Job items in your EF context, gets the City property value from each one, removes duplicates and then puts the remaining items into a List<T>. If the Job type has a City property then I don't see why that wouldn't compile. If I remember correctly, the Job type does have a City property and it is type String, so that would create a List<String> containing all unique city names for which a Job exists. If that's not what happens or that's not what you want, please explain further.
    csharp Code:
    1. cboCity.DataSource = db.Jobs.Select(a => a.City)
    2.                             .Where(a => a.Customer == cboCustomer.ValueMember)
    3.                             .Distinct()
    4.                             .ToList();
    In that case, you're calling Select first and Where second. I don't understand how it's confusing to you when I tell you to call Where first.
    [/HIGHLIGHT]
    This is the one that I've described the issue with numerous times but you seem determined not to hear it. I will say that I'm not executing anything here but rather doing this off the top of my head (I don't have your data to do otherwise). As I'm not infallible, there's a chance that what I'm telling you is wrong. Even if that's the case though, what I'm telling you is very simple so, if it's wrong, you should have found that out by trying my instructions and relayed that back to me by now. You haven't done that so I can only assume that you haven't followed the instructions I've provided.

    In this case, you first (you know, before anything else) take all the Jobs in your EF context and get the City property value from each. As I said, I believe that the City property is type String and contains the name of a city, so that Select call produces an enumerable list of String objects. You then call the Where method, which is used to filter data. You start with a list of String objects and proceed to try to filter them by their Customer property. ALERT! The list you're trying to filter contains String objects and String objects DO NOT have a Customer property. How can you filter something by something it doesn't have? Would you try to filter fish by how big their wings are?

    As I believe I have said before, it seems clear that what you're actually trying to do is to filter the Jobs by Customer, so that's exactly what you should do. You call Where FIRST, actually on the Jobs, and then you get the City from the items that make it through the filter. You may recall my example from before about the names of the people wearing red shirts. If you had a room full of people and you needed the names of the people wearing red shirts, would you start by taking down everyone's name, then look at the list of names and try to eliminate the ones of the people who were not wearing red? Of course you wouldn't, because a list of names tells you nothing about the colour of someone's shirt. A list of names is just text on a page and contains no information about the colour of the shirt worn by the person with that name. Similarly, a list of city names contains no information about the customer of the job that relates to that city. YOU NEED TO FILTER FIRST. Like this:
    csharp Code:
    1. cboCity.DataSource = db.Jobs.Where(a => a.Customer == cboCustomer.ValueMember)
    2.                             .Select(a => a.City)
    3.                             .Distinct()
    4.                             .ToList();
    That line takes all the jobs in the context, removes the ones that don't have a matching Customer, THEN gets the City value from each remaining Job item, then removes duplicate city names and then puts the remaining city names into a List<String>.

    Given that function syntax seems to be throwing you for some reason, it might be beneficial to you to use query syntax instead. It more closely resembles SQL syntax, but the 'select' always comes last. That's because that's how it actually gets executed, even with SQL. There are some parts that still require function calls but the bulk of the query can be written more like a SQL query, e.g.
    csharp Code:
    1. cboCity.DataSource = (from job in db.Jobs
    2.                       where job.Customer == cboCustomer.ValueMember
    3.                       select job.City).Distinct().ToList();

  5. #5

    Thread Starter
    Fanatic Member
    Join Date
    Mar 2013
    Location
    Minneapolis, MN
    Posts
    531

    Re: Setting Combobox DataSources using Entity Framework

    Thank you for your reply.

    In this code:
    Code:
            private void loadJobs()
            {
                using (var db = new ResourcePlanningEntities())
                {
                    dgvJobs.DataSource = db.Jobs.ToList();
    
                    cboCustomer.DataSource = db.Jobs.Select(a => a.Customer)
                        .Distinct()
                        .ToList();
    
                    cboCity.DataSource = db.Jobs.Where(a => a.Customer == cboCustomer.ValueMember)
                        .Select(a => a.City)
                        .Distinct()
                        .ToList();
    
                    cboCity.DataSource = (from job in db.Jobs
                                          where job.Customer == cboCustomer.ValueMember
                                          select job.City.Distinct().ToList();
                    
                }
    
            }
    This produces no datasource:
    Code:
                    cboCity.DataSource = db.Jobs.Where(a => a.Customer == cboCustomer.ValueMember)
                        .Select(a => a.City)
                        .Distinct()
                        .ToList();
    And this query syntax seems to have a problem with the semi-colon at the end:
    Code:
                    cboCity.DataSource = (from job in db.Jobs
                                          where job.Customer == cboCustomer.ValueMember
                                          select job.City.Distinct().ToList();
    Generally, the answer to my question seems to be that the SELECT comes at the end, rather than at the beginning such as 'SELECT * from tblJobs' as I am used to. Still, something is off.

    I will keep playing on my end.

    Thanks again!

  6. #6

    Thread Starter
    Fanatic Member
    Join Date
    Mar 2013
    Location
    Minneapolis, MN
    Posts
    531

    Re: Setting Combobox DataSources using Entity Framework

    The other frustration is, why doesn't this produce a data source?
    Code:
                    cboCity.DataSource = db.Jobs.Select(a => a.City)
                        .Distinct()
                        .ToList();
    but this does:
    Code:
                    cboCustomer.DataSource = db.Jobs.Select(a => a.Customer)
                        .Distinct()
                        .ToList();
    Not that it is what I am looking for, because I want the filter, but I cant help but think something else is wrong. They are both text fields.

    Thanks again!

  7. #7
    Super Moderator jmcilhinney's Avatar
    Join Date
    May 2005
    Location
    Sydney, Australia
    Posts
    110,299

    Re: Setting Combobox DataSources using Entity Framework

    Quote Originally Posted by ssabc View Post
    And this query syntax seems to have a problem with the semi-colon at the end:
    Code:
                    cboCity.DataSource = (from job in db.Jobs
                                          where job.Customer == cboCustomer.ValueMember
                                          select job.City.Distinct().ToList();
    It actually has a problem with the fact that you have an unpaired parenthesis. Compare your code to mine from earlier. I'll look at the rest later as my train is about to arrive at my destination.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width