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

Saving An Object To Database Quickly

1 Answer 72 Views
General Discussions
This is a migrated thread and some comments may be shown as answers.
This question is locked. New answers and comments are not allowed.
Solomon
Top achievements
Rank 1
Solomon asked on 30 Jul 2010, 11:25 PM
I have searched for quite awhile for an answer to this, but have not found anything. 

I would like to pass an object into my Business Layer to be Saved (Updated, not Inserted).

So my scenario is I have two projects (web project and class library BL) and only the BL is OpenAccess enabled. The web project has a bunch of CRUD screens. The typical EDIT operation goes like this - I get an OpenAccess Employee object with a GetEmployeeById(int employeeId) function in the BL, populate all the controls on the page from the object (FName, LName, etc.), the user changes the values and clicks Save. I get the Employee object again using the GetEmployeeByID function, change its values, and pass the Employee object to a SaveEmployee(Employee employee) method to be updated in the database. 

Since the ObjectScope that I retrieved the Employee from is long gone, is there an easy way save the data without getting it again in my SaveEmployee method? Is there some way I can attach this new object to a ObjectScope to be updated? I REALLY do not want to pass string values to a BL method to save an object, nor do I want to go out of my way to create skeleton objects. Maybe someday we will WCF this project as it grows, but now looking for quick and dirty for this proof of concept.

Thanks!

Sol

Here are my methods in the BL.

public static Employee GetEmployeeById(int id)
{
    IObjectScope objectScope = ObjectScopeProvider.ObjectScope();
 
    IQueryable<Employee> returnedEmployees = from x in objectScope.Extent<Employee>() where x.employeeId == id select x;
 
    if (returnedEmployees.Count() == 1)
    {
        return returnedEmployees.ToList()[0];
    }
 
    return null;
}

public static void SaveEmployee(Employee employee)
{
    var objectScope = ObjectScopeProvider.ObjectScope();
         
    //What can I do here???
}

Here is my code in the webpage

protected void Page_Load(object sender, EventArgs e)
{
    if (!IsPostBack)
    {
        lstPrefix.Items.Add(new RadComboBoxItem { Text = "", Value = null });
        foreach (var prefix in Prefix.GetAllPrefixs())
        {
            var item = new RadComboBoxItem {Text = prefix.Name, Value = prefix.PrefixID.ToString()};
            lstPrefix.Items.Add(item);
        }
     
        _employee = Employee.GetEmployeeById(EditID);
        lstPrefix.SelectedIndex = lstPrefix.Items.FindItemByValue(Convert.ToString(_employee.PrefixID)).Index;
        txtFirstName.Text = _employee.FirstName;
        txtMiddleName.Text = _employee.MiddleName;
        txtLastName.Text = _employee.LastName;
        txtSuffix.Text = _employee.Suffix;
        txtTitle.Text = _employee.Title;
    }
}


protected void btnSave_Click(object sender, EventArgs e)
{
    if (EditScreenMode == EditScreenModes.Edit)
    {
        _employee = Employee.GetEmployeeById(EditID);
    }
    else if (EditScreenMode == EditScreenModes.New)
    {
        _employee = new Employee();
    }
 
    if (lstPrefix.SelectedIndex != 0)
        _employee.PrefixID = Convert.ToInt32(lstPrefix.SelectedValue);
    _employee.FirstName = txtFirstName.Text;
    _employee.MiddleName = txtMiddleName.Text;
    _employee.LastName = txtLastName.Text;
    _employee.Title = txtTitle.Text;
 
    if (EditScreenMode == EditScreenModes.Edit)
    {
        //BusinessServices.Employee.SaveEmployee(employee);
    }
    else if (EditScreenMode == EditScreenModes.New)
    {
        BusinessServices.Employee.CreateEmployee(employee);
    }
 
    Response.Redirect("employees.aspx");
}



1 Answer, 1 is accepted

Sort by
0
Serge
Telerik team
answered on 03 Aug 2010, 07:15 PM
Hello Solomon,

 I can guess from your code that you have added this GetEmployeeById method to the Employee class. However in order to accomplish what you want you have to manage the object scope that is used. There is no way to attach an object from one scope to another automatically. You should implement the repository pattern and by that I mean just a class that looks like:

public class EmployeeRepository : IDisposable
{
    private IObjectScope scope;
 
    public EmployeeRepository()
    {
        this.scope = ObjectScopeProvider.GetNewObjectScope();
        this.scope.Transaction.Begin();
    }
 
    public Employee GetEmployeeByID(int id)
    {
        IQueryable<Employee> returnedEmployees = from x in this.scope.Extent<Employee>()
                                                 where x.EmployeeID == id
                                                 select x;
 
        if (returnedEmployees.Count() == 1)
        {
            return returnedEmployees.ToList()[0];
        }
        return null;
    }
 
    public void SaveChanges()
    {
        this.scope.Transaction.Commit();
    }
 
    public void Dispose()
    {
        this.scope.Dispose();
    }
}

Then if you modify the fields of an object that is retrieved through this GetObjectByID and call save changes, the object will be persisted in the database as it is still the same object scope that is accessed.

Do note however that calling SaveChanges will persist all changes made to objects that are retrieved through this particular instance of the EmployeeRepository class. 

This should be enough to get you started. Please contact us back if you face further trouble.

All the best,
Serge
the Telerik team
Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Public Issue Tracking system and vote to affect the priority of the items
Tags
General Discussions
Asked by
Solomon
Top achievements
Rank 1
Answers by
Serge
Telerik team
Share this question
or