views:

1238

answers:

1

Ok - I have two tables in the database, employees and companies. Here are the basic schemas for each

Table Companies
CompanyID - GUID - PK
CompanyName - NVarChar(100)
Other Descriptive Fields....

Table Employees
EmployeeID - GUID - PK
CompanyID - GUID - FK
Employee Descriptive Fields...

So now I have a one to many relationship as each company can have multiple employees. I have also created a dataRepository for my employee class with the following functions:

    Public Function GetEmployee(ByVal company As String, ByVal id As Guid) As DB.EmpWithComp.employee
    Dim emp As DB.EmpWithComp.employee = (From e In db.employees Where e.employeeID = id And e.company.companyName= company Select e).Single
    Return emp
End Function

    Public Sub save()
    db.SubmitChanges()
End Sub

Everything so far is working great. The issue comes when I need to edit an employee. Here are my controller functions

    <AcceptVerbs(HttpVerbs.Post)> _
Function Edit(ByVal id As Guid, ByVal company As String, ByVal formValues As FormCollection) As ActionResult
    Dim e As New DB.EmpWithComp.employee
    e = db.GetEmployee(company, id)
    Try
        UpdateModel(e)
        db.save()
        Return RedirectToAction("Index")
    Catch ex As Exception
        Return View(e)
    End Try
End Function

Function Edit(ByVal id As Guid, ByVal company As String) As ActionResult
    Dim e As New DB.EmpWithComp.employee
    e = db.GetEmployee(company, id)
    If Not e Is Nothing Then
        Return View(e)
    Else
        Return View("~/Views/Admin/Employees/NotFound.aspx")
    End If
End Function

The employee is found, the edit form is populated and the post function is firing as it should. However, my updateModel fails with no real explanation. I traced the code going through the updateModel and all attributes are being assigned the correct values. However, when the updateModel gets to the following section in the LinqToSql class, the value for company is Nothing and this is what is causing the failure

<Association(Name:="company_employee", Storage:="_company", ThisKey:="companyID", IsForeignKey:=true)>  _
 Public Property company() As company
  Get
   Return Me._company.Entity
  End Get
  Set
   Dim previousValue As company = Me._company.Entity
   **If ((Object.Equals(previousValue, value) = false)  _
      OrElse**  (Me._company.HasLoadedOrAssignedValue = false)) Then
    Me.SendPropertyChanging
    If ((previousValue Is Nothing)  _
       = false) Then
     Me._company.Entity = Nothing
     previousValue.employees.Remove(Me)
    End If
    Me._company.Entity = value
    If ((value Is Nothing)  _
       = false) Then
     value.employees.Add(Me)
     Me._companyID = value.companyID
    Else
     **Me._companyID = CType(Nothing, System.Guid)**
    End If
    Me.SendPropertyChanged("company")
   End If
  End Set
 End Property

What am I missing with the FK relationship? The previous value for company is set to the correct value going into the UpdateModel, but the current value is not set. If I manually set each property (e.firstname = request("firstname"), etc) and call my save method on the dataRepository or remove the relationship and use UpdateModel, everything works properly. I would rather use the UpdateModel as it makes the code cleaner, etc. Sorry for the lengthy post, but this is driving me nuts. Any ideas?

BTW, I am not trying to change the FK, just simply update the employee name.

+3  A: 

how does your view look like?

like this? <%=Html.TextBox("Company", ViewData.Model.Company)%>

if yes, UpdateModel would try to write the string in request("Company") to e.Company which isn`t a string but an object.

what you really want to change is the Employee.CompanyID right? you can do this by using a Hidden Input with the new ID or if you want to find the CompanyID by the CompanyName you could write your own ModelBinder.


EDIT

oh you dont event want to update the company, sry my fault. in that case you need to tell UpdateModel to ignore the company which is present in your POST

Function Edit(ByVal id As Guid, ByVal company As String...

you can do this by setting company as excluded property like this

Dim exclude() As String = {"company"}
UpdateModel(e, String.Empty, Nothing, exclude)

or what i prefer, you could start using prefixs for your fields like this

<%=Html.Textbox("Employee.Firstname", ViewData.Model.Firstname)>%

and call UpdateModel like this

UpdateModel(e, "Employee")

hth

marc.d
Nope, my view is just of employee data items (first name, last name, etc.). The relationship between these two tables is to be able to provide a list of employees for a certain company. The view binds correctly with the data, but it chokes on updating the model. It looks like the UpdateModel is getting upset that there is no company entity coming back from the form even though I am not updating anything to do with the company entitry including the FK constraint on the employee record.
Tommy
now i understand your problem, i updated my answer.
marc.d
thanks, that works perfectly! Sorry for the late response, haven't been coding this weekend.
Tommy