Microsoft 开发人员网络 > 论坛主页 > ADO.NET Entity Framework and LINQ to Entities > Setting a property which is an entity via a databound combobox.
提出问题提出问题
 

已答复Setting a property which is an entity via a databound combobox.

  • 2008年8月31日 0:24Kevin Donovan 用户奖牌用户奖牌用户奖牌用户奖牌用户奖牌
     

    Hi,

    I want to edit an entity (eg Business) via a databound form. Amongst its other properties this entity has properties which are themselves entities (eg BusinessType). I want to place a combo on the form for editing the BusinessType property. I'd set its datasource to a list of BusinessType, and it's DisplayMember to the Name property of the BusinessType. I'm not sure what to do with its ValueMember so that it will return the actual entity corresponding to the name selected in the combo box, and then update the databound BusinessType property of the Business entity accordingly.

     

    Kev

答案

  • 2008年9月7日 1:34Diego B VegaMSFT, 版主用户奖牌用户奖牌用户奖牌用户奖牌用户奖牌
     已答复

    Claudiu,

    Databinding works well to display and update objects that have properties of primitive types (i.e. that can be easily rendered to a simple control), but as you have noticied, Entity Framework represents relationships between objects as object references, instead of the typical key values.

    Fortunately, Entity Framework code-generated entity classes also contain a feature that allows reading and setting the keys of a related entity without actually using the object reference: EntityReferences.

    In your Product entity you will see a property named CategoryReference. And CategoryReference has a property named EntityKey. You cannot use databinding directly with EntityReferences, but you can extend the entity classes in a partial class in order to add those additional properties for databinding.

    This is a very simple example that uses the Product entity of a standard Northwind model:

    Code Snippet

    using System;

    using System.Collections.Generic;

    using System.Linq;

    using System.Text;

    using System.Data;

    using System.ComponentModel;

     

    namespace NorthwindModel

    {

        partial class Products

        {

            //this property would be redundant in serialization

            [property: NonSerialized]

            public int? CategoryReference_CategoryID

            {

                get

                {

                    if (this.CategoryReference == null)

                        return null;

                    if (this.CategoryReference.EntityKey == null)

                        return null;

                    return (int?)this.CategoryReference.EntityKey.EntityKeyValues[0].Value;

                }

                set

                {

                    if (value.HasValue)

                    {

                        //To notify others listening that the property is changing

                        this.OnPropertyChanging("CategoryReference_CategoryID");

                        //Always needs to create a new EntityKey object

                        this.CategoryReference.EntityKey =

                            new EntityKey(

                                "NorthwindEntities.Categories",

                                new EntityKeyMember[]

                                    { new EntityKeyMember("CategoryID",

                                        (object)value.Value) });

                        //To notify others listenging that the property has changed

                        this.OnPropertyChanged("CategoryReference_CategoryID");

                    }

                }

            }

        }

    }

     

    Hope this answers your question,
    Diego

     

  • 2009年7月6日 8:03Diego B VegaMSFT, 版主用户奖牌用户奖牌用户奖牌用户奖牌用户奖牌
     已答复

    Hello gaunmanuel & others,

    I have already responded to you in a new thread. People have had apparently mixed results in trying to follow the workaround proposed, but I can confirm that it works, so I would recommend to take a look at the code in the post marked and answer and try to adapt it to your case.

    A few things that I know might go wrong:

    1.     The sample code applies to Products – Categories as included in the sample Northwind database. In order to make this work in your model you will need to use the right names for properties and also in strings.

    2.     The code corresponds to a partial class file for "Products" (the default name obtained after creating the model from the Northwind database), that needs to be compiled alongside the Products type generated by EF.

    3.     Due to a limitation in WinForms design-time databinding, properties added in partial classes are not picked up at design time unless you compile it in a separate assembly. The solution in this case would be to move the EDMX model file, the generated code and also the proposed code for the partial class to a separate assembly, for instance, to a class library, and then add a reference to it from the project containing the form.

    4.     If the key exposed is also part of the primary key of the entity, it will not be possible to change the value. For instance, in the Northwind sample database, ProductID is a foreign key in [Order Details], but it is also part of the primary key, and therefore will be read-only in the entity.

    Besides this, we have added support for Foreign Key association in .NET 4.0. This is not included in beta 1, but will be available in the next public drops. Foreign Key associations make it possible to have both a navigation property and scalar FK properties associated with the same relationship. This should make this kind of databinding workaround unnecessary.

    Hope this helps,

    Diego


    This posting is provided "AS IS" with no warranties, and confers no rights.

全部回复

  • 2008年8月31日 17:57MatthieuMEZIL 用户奖牌用户奖牌用户奖牌用户奖牌用户奖牌
     建议的答复

    I do a small test without problem:

    Code Snippet

    public partial class Form1 : Form

    {

        Product product;

        public Form1()

        {

            InitializeComponent();

            var context = new NorthwindEntities();

            comboBox1.DataSource = context.Categories;

            comboBox1.DisplayMember = "CategoryName";

            product = context.Products.First();

            comboBox1.DataBindings.Add("SelectedItem", product, "Category");

        }

    }

     

     

  • 2008年8月31日 21:49Kevin Donovan 用户奖牌用户奖牌用户奖牌用户奖牌用户奖牌
     

    Hmm,

    I'm using the infragistics combo control, which doesn't have a SelectedItem property, guess that could be my problem. I'll post a question in the infragistics forum.

     

    Thanks,

    Kevin

  • 2008年9月1日 18:03pcc 用户奖牌用户奖牌用户奖牌用户奖牌用户奖牌
     
    Imagine this situation:
    2 tables
    first Products
    Id int
    Name nvarchar(50)
    CategoryId int

    second: Category
    Id int
    Name nvarchar(50)

    this 2 tables are related: Products.CategoryId->Category.Id

    I generated entities using Ado .net entity framework technology.
    For table Products field CategoryId is transformed into navigation properties wich return an object Category

    I want to edit products using DataGridView and specially ,i want to set CategoryId with a ComboBox
    (with tradition way i receive an exception and i don't know what to do)

    Your opinion may help me so please share it with me.


    Best Regards
    Claudiu



  • 2008年9月3日 15:28Arilson Santos 用户奖牌用户奖牌用户奖牌用户奖牌用户奖牌
     

     

    I have the same problem with DataGridView - DataBound - ComboBox
  • 2008年9月3日 16:51pcc 用户奖牌用户奖牌用户奖牌用户奖牌用户奖牌
     
    Good!
    We are two.
    Now let's find some help.
    For at least 1 week i am looking for an answer for my problem and nothing.
    I hope it's somebody who want to share with us his
    opinion.
     
    Claudiu
  • 2008年9月5日 23:01Eric Dettinger - MSFT版主用户奖牌用户奖牌用户奖牌用户奖牌用户奖牌
     

    Hi Claudiu,

     

    The way I'm interpreting your earlier post, you have a combo box and a data grid view. You want to fill the combo box with the Id of each Category entity. Whenever the selection changes in the combo box, you want to fill the data grid view with all the products whose id matches the selected Id.

     

    If I've interpreted this correctly, the following code will do what you want. It's written for Northwind, which looks very similar to the schema in your situation.

     

    NorthwindEntities _context = new NorthwindEntities();

     

    private void DetailsViewForm_Load(object sender, EventArgs e)

    {

    ObjectResult<Categories> categories =

    _context.Categories.Execute(MergeOption.NoTracking);

    categoriesComboBox.DataSource = categories;

    categoriesComboBox.DisplayMember = "CategoryID";

    }

     

    private void categoriesComboBox_SelectedIndexChanged(object sender, EventArgs e)

    {

    Categories category = categoriesComboBox.SelectedItem as Categories;

    if (null == category)

    return;

    ObjectQuery<Products> products = (ObjectQuery<Products>)_context.Products

    .Where(c => c.Categories.CategoryID == category.CategoryID);

    productsGridView.DataSource = products.Execute(MergeOption.NoTracking);

    }

  • 2008年9月6日 6:17pcc 用户奖牌用户奖牌用户奖牌用户奖牌用户奖牌
     
    I know!I don't speak english very well and maybe this it's the reason why you  don't understand my problem.

    In DataGridView i want to edit Products. in one field in this DataGridView is CategoryId wich edited 
    with the help of  DataGridViewComboBoxCell filled with Categories

    The generated entitie Products has the folowing public members:
    Id Int32
    Name string
    CategorytId typeof(Categories)(it's navigation properties and return an object))

    I set the members of DataGridViewComboBoxCell :
    DataSource=Categories
    DisplayMember="Name"
    ValueMember="Id"?
    Selecting a value from this
    DataGridViewComboBoxCell must set the CategoryId field from DataGridView (it's navigation properties and returns an entitie)

    and i get this error




    SystemArgumentException DataGridViewComboBoxCell value is not valid



    Claudiu


  • 2008年9月7日 1:34Diego B VegaMSFT, 版主用户奖牌用户奖牌用户奖牌用户奖牌用户奖牌
     已答复

    Claudiu,

    Databinding works well to display and update objects that have properties of primitive types (i.e. that can be easily rendered to a simple control), but as you have noticied, Entity Framework represents relationships between objects as object references, instead of the typical key values.

    Fortunately, Entity Framework code-generated entity classes also contain a feature that allows reading and setting the keys of a related entity without actually using the object reference: EntityReferences.

    In your Product entity you will see a property named CategoryReference. And CategoryReference has a property named EntityKey. You cannot use databinding directly with EntityReferences, but you can extend the entity classes in a partial class in order to add those additional properties for databinding.

    This is a very simple example that uses the Product entity of a standard Northwind model:

    Code Snippet

    using System;

    using System.Collections.Generic;

    using System.Linq;

    using System.Text;

    using System.Data;

    using System.ComponentModel;

     

    namespace NorthwindModel

    {

        partial class Products

        {

            //this property would be redundant in serialization

            [property: NonSerialized]

            public int? CategoryReference_CategoryID

            {

                get

                {

                    if (this.CategoryReference == null)

                        return null;

                    if (this.CategoryReference.EntityKey == null)

                        return null;

                    return (int?)this.CategoryReference.EntityKey.EntityKeyValues[0].Value;

                }

                set

                {

                    if (value.HasValue)

                    {

                        //To notify others listening that the property is changing

                        this.OnPropertyChanging("CategoryReference_CategoryID");

                        //Always needs to create a new EntityKey object

                        this.CategoryReference.EntityKey =

                            new EntityKey(

                                "NorthwindEntities.Categories",

                                new EntityKeyMember[]

                                    { new EntityKeyMember("CategoryID",

                                        (object)value.Value) });

                        //To notify others listenging that the property has changed

                        this.OnPropertyChanged("CategoryReference_CategoryID");

                    }

                }

            }

        }

    }

     

    Hope this answers your question,
    Diego

     

  • 2008年9月7日 15:22pcc 用户奖牌用户奖牌用户奖牌用户奖牌用户奖牌
     
    Ado .Net Entity Data Model it's a good technology.The generated classes are good things for programmers.
    Anyway , the code what you show me could be very well generated(if i have 50 tables with 3 navigation properties each ,i must write this code again and again ...)
    or controls used to to edit this entities (like DataGridViewComboColumn) could be upgraded to recognize NavigationProperties and have the properly behaviour.Maybe in next release of sp.

    Thanks for your kindness.

    Claudiu
  • 2008年9月11日 13:09Arilson Santos 用户奖牌用户奖牌用户奖牌用户奖牌用户奖牌
     

     

    But Diego,

     

    I tried something like that and I still have a problem.

    In a combo the "Description" doesn't appear but just its ID.

  • 2008年9月11日 13:13pcc 用户奖牌用户奖牌用户奖牌用户奖牌用户奖牌
     
    try setting DisplayMember of ComboBox

    for me  the supplied snippet code worked just fine.

    claudiu
  • 2008年9月11日 14:29Arilson Santos 用户奖牌用户奖牌用户奖牌用户奖牌用户奖牌
     

    Diego,

     

    Yours solutcion worked here at least the DataGridViewCombo show the "description"

    but if I change the DataGridViewCombo's value the change doesn't occur.

    Ex.

    Description   Value

    A          1

    B          2

     

    If I change from A to B (in a DataGridViewComboBoxColumn) and get the value, it still is 1.

     

  • 2008年9月11日 18:44AnneMMA 用户奖牌用户奖牌用户奖牌用户奖牌用户奖牌
     

    Diego,

     

    Your code example for working with entity references was very helpful. I have an additional question about binding, though. You indicated that it works well to display and update object properties that have primitive types. Although I can get my bound controls (text boxes in this case) to display the data in an object, the data isn't updated automatically when I make changes to the values in the controls. Instead, I have to manually assign the values to the object properties. Am I missing something or is this the way this is supposed to work?

     

    Anne 

     

  • 2008年9月12日 12:32Arilson Santos 用户奖牌用户奖牌用户奖牌用户奖牌用户奖牌
     

    Sincerally, I'll return to Linq To Sql Sad

  • 2009年2月5日 1:34Yann Duran 用户奖牌用户奖牌用户奖牌用户奖牌用户奖牌
     
    Hi Diego,

    Are you *seriously* suggesting that the only way to bind to a combobox using EF is to *manually* extend every generated class that you need to use in binding?

    I sincerely hope not!

    I'm having trouble at the moment, binding navigation properties to comboboxes & am looking for the right way to do it (or a way that works), but I hope I don't have to do what you've suggested, that's *crazy*.

    Yann
  • 2009年2月6日 0:57Yann Duran 用户奖牌用户奖牌用户奖牌用户奖牌用户奖牌
     
    Diego,

    Well, at least I managed to bind an EF entity's navigattion property to a WinForms combobox now, using the method you described (had to bind the SelectedValue property of the combobox to the newly created property) & I'm able to display & edit values correctly.

    Could you tell me *why* these "properties" are not generated automatically as suggested by Claudiu?

    Will this be changed at some point? An update to EF 1? Or in EF 2?

    Seems to be quite an oversight, seeing as this is such a basic requirement & as so much else is already generated. I would suggest, that anything that needs to be "extended" over & over, as in this case, is a good candidate for inclusion in the automatically generated code.

    Even if there was an "option" to generate it or not, to appease anyone who is already concerned about the current amount of generated code.

    Thanks,

    Yann
  • 2009年2月18日 0:03Diego B VegaMSFT, 版主用户奖牌用户奖牌用户奖牌用户奖牌用户奖牌
     
    Yann,

    It is actually a great question. In .NET 3.5 SP1, the EDM (the conceptual model on which EF operates) models relationships as independent objects from entities. The fact that there is a FK that has a value that matches a PK in the database is kind of an implementation detail that we abstract away in the model. I understand this doesn't work very well with the way many are used to think about database applications, including databinding scenarios in which the FKs are handy, but on the ORM camp, this is a relatively common pattern.

    Supporting FKs alongside navigation properties as valid representation of relationships poises a few challenges. You may be interested in the following EF Design blog post in which we ask for feedback on this subject d http://blogs.msdn.com/efdesign/archive/2008/10/27/foreign-keys-in-the-conceptual-and-object-models.aspx.

    Thanks,
    Diego
    This posting is provided "AS IS" with no warranties, and confers no rights.
  • 2009年2月18日 1:15Josh56 用户奖牌用户奖牌用户奖牌用户奖牌用户奖牌
     
    Diego - I read through this thread as well as the EF blog responses in the link you just posted.  This is all very interesting, and I can see both sides of the argument for FK's, however, at this point, how do I bind an entity as the datasource for a combobox in a datagrid when I can't set the ValueMember property in the databinding?  The issue is as you pointed out there is no FK exposed on the related table, which is fine- I'm ok with using the hydrated entity which is already available since I loaded the FK table's data into the drop down via EF- however, there is not a navigation property available for the related table.  I think at the very least if a navigation property with the name of the entity was exposed (i.e. "tblProductTypes") and could be set as the valuemember in a combobox databinding scenario, my needs would be met, and the ORM principles would also be preserved since a real entity would exist, and a real object relationship would exist.  At this point I'm hard pressed to recommend to my team that we go forward with EF with such a glaring shortfall- manually creating a partial class of the EntityObject to handle this FK scenario is just not an acceptable solution.
    Thanks
  • 2009年2月18日 1:29Yann Duran 用户奖牌用户奖牌用户奖牌用户奖牌用户奖牌
     
    Hi Diego,

    Thanks for taking the time to answer my question (well, sort of, lol). I understand that things sometimes need to change when a new paradigm gets introduced. What I don't understand is how MS can expect developers to use that new paradigm if they can't *easily* do the things that they need to do & are used to doing.

    Binding to a combobox is such a basic operation, that seems to have been overlooked. It's all well & good to "abstract away the FK details", but leaving developers hanging, with no replacement way (& a *manual* way does *not* count) of doing what is required in their apps is not only "not acceptable" (as Josh rightly points out), it's also highly likely to severely curb the number of people willing to move to EF (again as Josh has pointed out for his own team).

    I hope my "great question" will give the EF developers encouragement to give consideration as to how developers are supposed to use EF entities with controls such as comboboxes.

    If any of the people using EF in serious apps have found a non-manual way, it would be good to publish their method for all developers to consider. Right now it's kind of "everyone roll your own method". That's crazy!

    Yann
  • 2009年2月18日 9:54Diego B VegaMSFT, 版主用户奖牌用户奖牌用户奖牌用户奖牌用户奖牌
     

    Yann and Josh,

    I can assure you that our team agrees this an important issue. Great thanks for your feedback, and please stay tuned.

    Diego

    PS: On the particular issue that Josh describes, I am not sure I understand the explanation. By default there is going to be a navigation property that will hold a reference to the object on the other end. For instance, Product has a Category navigation property, and Post has an Author navigation property. The fact is that generally speaking, databinding doesn't know how to handle properties that are not of primitive types.



     


    This posting is provided "AS IS" with no warranties, and confers no rights.
  • 2009年2月18日 15:50Josh56 用户奖牌用户奖牌用户奖牌用户奖牌用户奖牌
     

    Diego- thanks for responding, I basically was describing the same issue as Yann- i.e.:

    If you had these two tables:

    tblProduct (pkProductID, Description, Price, fkTypeID)

    tblType (pkTypeID, TypeDescription)

    The Entity Sets created for these tables would look like:

    tblProduct (scalar[pkProductID, Description, Price] Navigation [tblType])

    tblType (scalar[pkTypeID, TypeDescription] Navigation [tblProduct])

    So, in my datagrid that is bound to tblProduct, and has a column that is of type combobox which is bound to tblType, what value do I set for the ValueMember?  Like you said, generally speaking you can only bind the valuemember property to a primitive type, yet you could not in this case choose pkTypeID, since the tblProduct entity expects an object reference.  I know there is not a good answer for this problem right now, I just wanted to clarify my question.

    Thanks,

    Josh

       

  • 2009年5月7日 9:46AlexS-D 用户奖牌用户奖牌用户奖牌用户奖牌用户奖牌
     包含代码

    Diego,

    I'm also having this problem! (It's really not easy!)
    I've followed your steps above, but I'm at a loss and simply do not understand. The above code is placed into its own class, within the same project as the edmx model... Hopefully, I've got this right. But I can't figure out

    [property: NonSerialized]
    public
    int? CategoryReference_CategoryID

    I get an error "Attribute 'NonSerialized' is not valid on this declaration type. It is only valid on 'field' declarations." for my own project

    Within my project I have tblCountry and have found the reference to tblTimeZoneReference but no property for EntityKey

            [global::System.ComponentModel.BrowsableAttribute(false)]
    
            [global::System.Runtime.Serialization.DataMemberAttribute()]
    
            public global::System.Data.Objects.DataClasses.EntityReference<tblTimeZones> tblTimeZonesReference
    
            {
    
                get
    
                {
    
                    return ((global::System.Data.Objects.DataClasses.IEntityWithRelationships)(this)).RelationshipManager.GetRelatedReference<tblTimeZones>("IBISModel.FK_tblCountry_tblTimeZones", "tblTimeZones");
    
                }
    
                set
    
                {
    
                    if ((value != null))
    
                    {
    
                        ((global::System.Data.Objects.DataClasses.IEntityWithRelationships)(this)).RelationshipManager.InitializeRelatedReference<tblTimeZones>("IBISModel.FK_tblCountry_tblTimeZones", "tblTimeZones", value);
    
                    }
    
                }
    
            }
    
    
    

    Please could somebody point out what I'm doing wrong!!!!

    All I want to do is update my table tblCountry with a foreign key (Combobox) to tblTimeZone in WPF using EF in a WCF Service.
    I can get the list of TimeZones, and display the correct relationship within Country but when I update I get an error:
    "The object could not be added or attached because its EntityReference has an EntityKey property value that does not match the EntityKey for this object."

    The update that fails:

            public void Update(tblCountry dsCountry)
            {

                context.Attach(dsCountry);
                dsCountry.SetAllModified(context); // custom extension method

                try
                {

                    context.SaveChanges(true);
                }
                catch (OptimisticConcurrencyException e)
                {
                    // someone else changed the data, throw
                    throw (e);
                }
            }

    So now I'm here in this thread, after 3 weeks!! of trying to get it sorted. Please Please help! :S

     

     

  • 2009年5月18日 10:02MagicMax 用户奖牌用户奖牌用户奖牌用户奖牌用户奖牌
     包含代码

    Hello!

    AlexS-D - did you found the solution for your problem? I have the same issue related with ComboBox bounded and Update on server side....

    Thank you!

  • 2009年6月16日 23:37Anil Mujagic 用户奖牌用户奖牌用户奖牌用户奖牌用户奖牌
     
    Any news on this issue?

    Thanks...
  • 2009年7月2日 17:00gaunmanuel 用户奖牌用户奖牌用户奖牌用户奖牌用户奖牌
     

    Diego.
    This problem is from August 2008...... today is july 2009 One year has passed, and no solution.

    How can I use a DataGridViewComboBoxColumn within a dataGridView?
    Do you have an example? of course using EF.

    Thanks..

  • 2009年7月3日 12:20Anil Mujagic 用户奖牌用户奖牌用户奖牌用户奖牌用户奖牌
     

    Diego.
    This problem is from August 2008...... today is july 2009 One year has passed, and no solution.

    How can I use a DataGridViewComboBoxColumn within a dataGridView?
    Do you have an example? of course using EF.

    Thanks..


    Hi Diego,

    Maybe you can add "Self" read-only property to your entity which will return the object itself:

    public Customer Self
    {
        get
        {
            return this;
        }
    }

    I found this in recent book I read. It's not great solution because you have to add it to every entity where you need it, but at least it is workaround until we get VS2010 and more control over generated code from EDM Designer.

    Hope it helps!

    Regards!

    Anil
  • 2009年7月3日 12:23Anil Mujagic 用户奖牌用户奖牌用户奖牌用户奖牌用户奖牌
     
    Hi Diego,

    Maybe you can add "Self" read-only property to your entity which will return the object itself:

    public Customer Self
    {
        get
        {
            return this;
        }
    }

    I found this in recent book I read. It's not great solution because you have to add it to every entity where you need it, but at least it is workaround until we get VS2010 and more control over generated code from EDM Designer.

    Hope it helps!

    Regards!

    Anil
    ... :) I wanted to say: Hi gaunmanuel...
  • 2009年7月6日 8:03Diego B VegaMSFT, 版主用户奖牌用户奖牌用户奖牌用户奖牌用户奖牌
     已答复

    Hello gaunmanuel & others,

    I have already responded to you in a new thread. People have had apparently mixed results in trying to follow the workaround proposed, but I can confirm that it works, so I would recommend to take a look at the code in the post marked and answer and try to adapt it to your case.

    A few things that I know might go wrong:

    1.     The sample code applies to Products – Categories as included in the sample Northwind database. In order to make this work in your model you will need to use the right names for properties and also in strings.

    2.     The code corresponds to a partial class file for "Products" (the default name obtained after creating the model from the Northwind database), that needs to be compiled alongside the Products type generated by EF.

    3.     Due to a limitation in WinForms design-time databinding, properties added in partial classes are not picked up at design time unless you compile it in a separate assembly. The solution in this case would be to move the EDMX model file, the generated code and also the proposed code for the partial class to a separate assembly, for instance, to a class library, and then add a reference to it from the project containing the form.

    4.     If the key exposed is also part of the primary key of the entity, it will not be possible to change the value. For instance, in the Northwind sample database, ProductID is a foreign key in [Order Details], but it is also part of the primary key, and therefore will be read-only in the entity.

    Besides this, we have added support for Foreign Key association in .NET 4.0. This is not included in beta 1, but will be available in the next public drops. Foreign Key associations make it possible to have both a navigation property and scalar FK properties associated with the same relationship. This should make this kind of databinding workaround unnecessary.

    Hope this helps,

    Diego


    This posting is provided "AS IS" with no warranties, and confers no rights.

  • 2009年7月6日 11:13Se3ker385 用户奖牌用户奖牌用户奖牌用户奖牌用户奖牌
     
    I think that people are looking at this the wrong way, this problem is not the limitation of Entity framework, but rather a limitation of WinForms Combobox control.

    The combobox returns only primitive types, thats why it cant return an entity object.

    Combox has two modes, unbound and databound, in databound mode you set its DataSource, DisplayMember and ValueMember properties. So if you set the ValueMember becuse return type is an object the combobox cannot process it.

    3rd party developers, like for instance DevExpress, they seperated unbound mode and databound mode to two controls, one is ordinary Combobox other is a LookupEditor, The lookup editor also has 3 properties DataSource, DisplayMember and ValueMember, if you set the DataSourceto EF entity list and set its DisplayMember, but leave the ValueMember blank the LookupEditor returns an object, the relatanship.

    In the next version id rather that relationships remain 1st class and that the Combobox changes its functionality, then the EF changes to include FK's so we can bind to Combobox. 


    VB.NET to C# http://www.developerfusion.com/tools/convert/vb-to-csharp/
  • 2009年7月6日 11:53Yann Duran 用户奖牌用户奖牌用户奖牌用户奖牌用户奖牌
     
    Hi Se3ker385 ,

    You're quite right, I hadn't considered it from that angle. On the other hand though, the "workaround" does show that it's possible to make the existing combo box work. My only complaint was that it had to be done manually.

    Thanks for reminding us of the other side of the equation.

    Yann
  • 2009年10月19日 7:16Gentledepp 用户奖牌用户奖牌用户奖牌用户奖牌用户奖牌
     包含代码

    Hi!

    I had the same problem and found the solution:

    In our architecture, we convert our Entities to Dtos (POCOs) and vice versa. For a clean architecture the EntityKey property (which is clearly Entity Framework internal) is not serialized.

    Therefore, when we convert all Dtos to Entities again, we need to set the EntityKey properties of the References to match those entities that already exist in the database. Otherwhise they would be recreated.

    Customer.AddressReference.EntityKey = orig.EntityKey;
    

    However a problem arises, when the Customer entity that came in, already has an Address entity set that has no EntityKey either, which almost always is the case, as we send the object graph to client and back again. If you set the EntityKey on the "AddressReference" property in this case, it is NOT SET on the entity in the "Address" property. Therefore you will geht the error:
    "the object could not be added or attached because its EntityReference has an EntityKey blablabla..."
    when you want to save the Customer entity.

    Therefore you need to do the following workaround:

    //temporary save incoming value
    var address = Customer.Address
    //Remove the Address entity from Customer
    Customer.Address = null;
    //set the entity key
    Customer.AddressReference.EntityKey = new EntityKey("MyDemo.Addresses", "AddressID", address.AddressID);
    

    Hope that helps you guys. ;)

    Warning: If you set the AddressReference.EntityKey first and remove the Address afterwards, the EntityKey will be null again!

    Warning: If you set the EntityKey on the Address Entity directly, you will get the error, that there already exists another entity in the ObjectContext with the same key.

    As you see - I tried 'em all ;)

  • 2009年11月22日 10:10Eric Commelin 用户奖牌用户奖牌用户奖牌用户奖牌用户奖牌
     包含代码
    Hello,

    First, I am quite a beginner with Entity Framework, so excuse me if I say something realy silly.
    I had the same DataGriwViewComboBoxColumn problem while testing Entity Framework.
    The proposed solution seemed quite complicated, I used something else.
    Because I hate the DataGridView control (being mostly an ASP.Net developper, I find it very difficult to use when I need it, one a year...), I assumed it was a grid problem and not an entity framework problem.
    The DataGridViewComboBoxColumn filled with categories does not use the entity object as ValueMember, so the navigation property of the product cannot be databound.
    I used an "adapter". Here is a small test winform :
    public partial class FormTest : Form {
      private NorthwindEntities Northwind;
      public FormTest() {
        InitializeComponent();
    
        this.Northwind = new NorthwindEntities();
    
        DataGridViewComboBoxColumn cbcCategories = new DataGridViewComboBoxColumn();
        cbcCategories.DataPropertyName = "Categories";
        cbcCategories.DisplayMember = "CategoryName";
        cbcCategories.ValueMember = "TheCategoryItself";
        cbcCategories.DataSource = Northwind.Categories.Select( c => new { CategoryName = c.CategoryName, TheCategoryItself = c } );
        DgvProducts.Columns.Add( cbcCategories );
    
        DataGridViewTextBoxColumn tbcProductName = new DataGridViewTextBoxColumn();
        tbcProductName.DataPropertyName = "ProductName";
        DgvProducts.Columns.Add( tbcProductName );
    
        DgvProducts.AutoGenerateColumns = false;
        DgvProducts.DataSource = Northwind.Products;
      }
    
      protected override void OnClosed( EventArgs e ) {
        base.OnClosed( e );
        Northwind.SaveChanges();
      }
    }
    
    
    

    Everything seems OK but the code is to simple and I am a newbie so it is (very) possible I missed something.

    Best regards (and sorry for my french english).

    Eric.

    • 已编辑Eric Commelin 2009年11月22日 10:12B and U are not supported in code blocks !
    •