Entity Framework navigation property?

6 posts, 0 answers
  1. Lextendo
    Lextendo avatar
    12 posts
    Member since:
    Feb 2010

    Posted 08 Feb 2010 Link to this post

    Hi,
    In my appointment I require a custom field. My schedulers datasource is an EntityDataSource, with one of the entity properties of the appointment is a "donors", another entity.This "donors" propertie must be bound to a RadComboBox which contains a selection of donors in the insert/edit templates of the appointement. 
    I inserted an appointment directly in the database for testing purposes (so I can atleast show the appointment)

    So my scheduler defenition looks like this:
    <telerik:RadScheduler runat="server" ID="rsDonationSchedule" DayStartTime="08:00:00" 
                                                DayEndTime="18:00:00" TimeZoneOffset="03:00:00" DataSourceID="edsDonationSchedule" 
                                                DataKeyField="DonationScheduleId" DataStartField="Start" DataEndField="End" DataSubjectField="Subject" 
                                                CustomAttributeNames="Donors" OnAppointmentInsert="rsDonationSchedule_OnAppointmentInsert" > 
                                                <AdvancedForm Modal="true" /> 
    Notice the CustomAttributeNames="Donors"

    Now when I use the AppointmentTemplate like this:
    <AppointmentTemplate> 
       <%# Eval("Subject") %><%# Eval("Donors.SurName")%> 
    </AppointmentTemplate> 
    The SurName of the donor is not displayed, but there is no error message either?

    I can't get an appointment inserted (or updated) either....
    <InlineInsertTemplate> 
        <span> 
            <table> 
                <tr> 
                    <td> 
                        <asp:Label ID="Label3" AssociatedControlID="TitleTextBox" runat="server">Onderwerp</asp:Label><asp:TextBox 
                            ID="TitleTextBox" runat="server" Text='<%# Bind("Subject") %>' Width="90%" Height="20px"></asp:TextBox> 
                    </td> 
                </tr> 
                <tr> 
                    <td> 
                        <asp:Label ID="Label4" AssociatedControlID="rcbDonors" runat="server">Donor</asp:Label><telerik:RadComboBox 
                            ID="rcbDonors" runat="server" DataSourceID="edsDonoren" DataTextField="DonorScheduleLabel" 
                            DataValueField="DonorId" MarkFirstMatch="true" SelectedValue="<%# Bind('Donors.DonorId') %>" /> 
                    </td> 
                </tr> 
                <tr> 
                    <td> 
                        <asp:Label ID="Label5" AssociatedControlID="txtDescription" runat="server">Info</asp:Label><asp:TextBox 
                            ID="txtDescription" runat="server" Text='<%# Bind("Description") %>' Width="90%" 
                            TextMode="MultiLine" Height="20px"></asp:TextBox> 
                    </td> 
                </tr> 
                <tr> 
                    <td> 
                        <asp:LinkButton ID="InsertButton" runat="server" CommandName="Insert"
                            <asp:Image runat="server" ID="insertImage" ImageUrl="Images/ok.png" AlternateText="insert" /> 
                        </asp:LinkButton> 
                        <asp:LinkButton ID="InsertCancelButton" runat="server" CausesValidation="False" CommandName="Cancel"
                            <asp:Image runat="server" ID="Image2" ImageUrl="Images/cancel.png" AlternateText="cancel" /> 
                        </asp:LinkButton> 
                    </td> 
                </tr> 
            </table> 
        </span> 
    </InlineInsertTemplate> 

    There's an error message on the datasource inserting event (void edsDonationSchedule_Inserting(object sender, EntityDataSourceChangingEventArgs e)):
    Exception {"Error while setting property 'Donors': 'This property descriptor does not support the SetValue method.'."} System.Exception {System.Web.UI.WebControls.EntityDataSourceValidationException}

    I think need to set the DonorsReferenceEntityKey upon saving, but how would I do this?
    When I catch event OnAppointmentCommand from my scheduler, I can add attributes, but adding "DonorsId" or "Donors.DonorsId" will fail since these are not properties off my appointment entity. Donors is, but it is an object, and it looks like I can only add "string" attributes...

    Do I need to abandon the EF path? 




  2. robertw102
    robertw102 avatar
    265 posts
    Member since:
    Jul 2007

    Posted 08 Feb 2010 Link to this post

    The problem is the CustomAttributes property. The CustomAttributes isn't data-bound like the other fields. If you want to hold the DonorId field you can set CustomAttributes="DonorId" and then handle the AppointmentCommand event. In the AppointmentCommand event, you check that the command name is insert/update, then you can search for the RadComboBox control for donors by calling e.Container.FindControl([CONTROL_NAME]) and then setting the SelectedValue of the control to the CustomAttribute["DonorId"] of the appointment object.

    I hope that helps.
  3. UI for ASP.NET Ajax is Ready for VS 2017
  4. robertw102
    robertw102 avatar
    265 posts
    Member since:
    Jul 2007

    Posted 08 Feb 2010 Link to this post

    I forgot to mention this in my last post.

    To pass it to the datasource you could set the DonorId parameter to the customattribute or you could just ignore the whole customattribute property and just create SessionParameter for the DonorId field in your datasource and then set it when the way I posted before, but to the session variable.
  5. Lextendo
    Lextendo avatar
    12 posts
    Member since:
    Feb 2010

    Posted 09 Feb 2010 Link to this post

    Robert,
    Thanks for your response. The problem is my datasource entity does not have a DonorID...
    It holds a navigationproperty Donors. This poroperty does have an DonorsId. To clarify:

    edsDoneationSchedule contains a collection of donor_DonationSchedule entities. These donor_DonationSchedule entities conform to the scheduler required fields like start/end/subject/etc.. Creating/Editing these 'appointment entities' works fine. There is a working example with an entitydatasource in the demo-section of this site.

    Now i like to add a custom 'field' a donor_Donors. So in the database  this is 'just' a Guid (DonorsId), however, to the EF it is a navigation property, hence donor_DonationSchedule does not contain a DonorsId!
    I can't seem to 'intercept' the insert/update of the edsDoneationSchedule :(  At that point I would set the correct reference to donor_DonationSchedule.Donors with the combobox selected value.

    Maybe I should 'revert' to an sqldatasource, but this would 'break' the architecture since we use EF...
  6. robertw102
    robertw102 avatar
    265 posts
    Member since:
    Jul 2007

    Posted 09 Feb 2010 Link to this post

    If you want to set the DonorId field for donor_Donors object that's associated with donor_DonationSchedule object. You intercept the Inserting/Updating events of the EntityDatasource object. You then cast the object being created/updated to the donor_DonationSchedule object and then access the Donors object and set the DonorId of that donor. 

    Like so:

    protected void LinqSource_Inserting(object sender, LinqDataSourceInsertEventArgs e) 
        { 
            // get object being inserted 
            donor_DonationSchedule object = (donor_DonationSchedule)e.NewObject; 
            // set DonorID 
            object.Donors.DonorId = Session("DonorId"); 
        } 

    This is using LinqDataSource, but I think it works the same for EntityDataSource as well.

    I think that is what your asking for. I don't understand how the schedule doesn't have a DonorId fields, but it has a Donors object. How are you linking the two tables? Is it a different name or is there no link?





  7. Lextendo
    Lextendo avatar
    12 posts
    Member since:
    Feb 2010

    Posted 09 Feb 2010 Link to this post

    I catch the inserting event:
    void edsDonationSchedule_Inserting(object sender, EntityDataSourceChangingEventArgs e) 
        donor_DonationSchedule sch = (donor_DonationSchedule) e.Entity; 
        using (DonorContext context = new DonorContext()) 
        { 
            Guid gid = new Guid("00155285-740b-4b7b-9d7f-9d1100d4489e"); 
            sch.Donors = context.donor_DonorSet.FirstOrDefault(d => d.DonorId == gid); 
        } 

    However e.Entity == null && e.Exception == "Error while setting property 'Donors': 'This property descriptor does not support the SetValue method."
    I hardcoded the donor_Donors.DonorsId just to see if it works. It doesn't :(

    However... I did get it to work :) Not very elegantly but still ;)

            protected void rsDonationSchedule_OnAppointmentInsert(object sender, SchedulerCancelEventArgs e) 
            { 
                _insertSched = new donor_DonationSchedule 
                                   { 
                                       DonationScheduleId = GuidComb.New(), 
                                       End = e.Appointment.End, 
                                       Start = e.Appointment.Start, 
                                       Subject = e.Appointment.Subject, 
                                       Description = e.Appointment.Description 
                                   }; 
                using (DonorContext context = new DonorContext()) 
                { 
                    Guid gid = new Guid("00155285-740b-4b7b-9d7f-9d1100d4489e"); 
                    _insertSched.Donors = context.donor_DonorSet.FirstOrDefault(d => d.DonorId == gid); 
                    context.AddObject("donor_DonationScheduleSet", _insertSched); 
                    context.SaveChanges(); 
                } 
     
                e.Cancel = true
                ((RadScheduler)sender).Rebind(); 
            } 
    Basically I just cancel the scheduler insert and doing it manually. Code is not complete (recurrance, using the combobox selected value, etc) but it does insert the data correct into the database.

    Next challenge is updating the appointment and displaying the donor_Donors.SurName in the <AppointmentTemplate>.

    Thanks for helping me looking in the right direction Robert. 
Back to Top
UI for ASP.NET Ajax is Ready for VS 2017