This is a migrated thread and some comments may be shown as answers.

Entity Framework navigation property?

5 Answers 138 Views
Scheduler
This is a migrated thread and some comments may be shown as answers.
Lextendo
Top achievements
Rank 1
Lextendo asked on 08 Feb 2010, 02:15 PM
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? 




5 Answers, 1 is accepted

Sort by
0
robertw102
Top achievements
Rank 1
answered on 08 Feb 2010, 07:30 PM
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.
0
robertw102
Top achievements
Rank 1
answered on 08 Feb 2010, 07:32 PM
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.
0
Lextendo
Top achievements
Rank 1
answered on 09 Feb 2010, 01:13 PM
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...
0
robertw102
Top achievements
Rank 1
answered on 09 Feb 2010, 02:46 PM
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?





0
Lextendo
Top achievements
Rank 1
answered on 09 Feb 2010, 07:36 PM
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. 
Tags
Scheduler
Asked by
Lextendo
Top achievements
Rank 1
Answers by
robertw102
Top achievements
Rank 1
Lextendo
Top achievements
Rank 1
Share this question
or