views:

508

answers:

2

Hello,

I am using a FormView control to edit a record fetched using a LinqDataSource. In essence, the markup for the FormView and the data source looks like this:

<asp:FormView ID="RuleInstancePropertiesFormView" runat="server" DataKeyNames="RuleInstanceId"
DataSourceID="RuleInstanceDataSource" DefaultMode="Edit" Visible="false"
CssClass="PropertiesTable">
<EditItemTemplate>
    <asp:Label ID="RuleInstanceId" runat="server" Text='<%# Eval("RuleInstanceId") %>' />

    <telerik:RadTextBox ID="RuleInstanceNameTextBox" 
                        runat="server"
                        Text='<%# Bind("Rule.Name") %>' />

    <telerik:RadTextBox ID="LimitIndexTextBox"
                        runat="server"
                        Text='<%# Bind("LimitIndex") %>' />
</EditItemTemplate>
</asp:FormView>
<asp:LinqDataSource ID="RuleInstanceDataSource" runat="server"
    ContextTypeName="Questionnaire.QuestionnairesDataContext"
    TableName="RuleInstances" EnableUpdate="true">
</asp:LinqDataSource>

The record I am editing has a foreign key reference to another table, namely the "Rule" table. In the FormView, I need to edit fields in this foreign key table (I have a binding to the Rule.Name field in the above code).

When I try to save my changes, the local field (LimitIndex) is saved correctly in the database, but the foreign field (Rule.Name) isn't. I'm a bit puzzled by this, as the FormView correctly fetches the current value of Rule.Name, but refuses to persist it back to the LINQ object.

I hope anyone can help, thanks :)

A: 

You're specifying which table to use as a datasource using the TableName property. This controls which table Linq2Sql will update and so is limiting the update to just the RulesInstances table.

Adam
Okay, that was what I thought. Thanks! Do you have any ideas as to what I can do then? I think the only option I have right now is to do all the data binding in the code-behind.
Ulrik Rasmussen
Yes unfortunately you're going to have do this in the code behind.
Adam
A: 

Okay, I found an alternative (but not elegant) solution. I use an ObjectDataSource instead of a LinqDataSource. I have then defined an class

public class RuleInstanceProjection {
    public RuleInstanceProjection(){}

    // Bind properties from the LINQ object.
    public RuleInstanceProjection(RuleInstance instance) { ... }

    public int RuleInstanceId {get; set;}
    public string Rule_Name {get;set;}
    ...
}

The object above takes a RuleInstance as constructor, and updates its own properties with all the values that I need in the FormView. I then configure the ObjectDataSource to use another custom class, RuleInstanceProjectionDS, as data source. This class handles updates and inserts of my custom RuleInstanceProjection class:

public class RuleInstanceProjectionDS
{
    public RuleInstanceProjectionDS() { }

    public RuleInstanceProjection GetRuleInstance(int ruleInstanceId)
    { /* Retrieve the RuleInstance, and instantiate 
         a RuleInstanceProjection object */ }

    public void SaveInstanceProjection(InstanceProjection projection)
    { /* Map fields back to the LINQ objects and submit. */ }
}

I can therefore handle all mappings in these two classes. Now, I only have to decide if this is actually better than updating the GUI controls directly...

I must say it isn't the most elegant solution, and I hope there will be a better data binding framework in later versions of ASP.NET. The current one only seems to handle the most trivial cases :(.

Ulrik Rasmussen