expressappframework-403616-data-manipulation-and-business-logic-create-read-update-and-delete-data-create-a-new-object.md
You can use following Object Space methods to create a new object:
IObjectSpace.CreateObjectCreates an object of the specified type.IObjectSpace.CreateObject<ObjectType>Creates an object of the type designated by the specified generic type parameter.XafApplication.CreateObject<T>Creates an object of the type designated by the generic type parameter.IObjectSpace.IsNewObjectIndicates whether a specified object has been created but has not been saved to the database.IObjectSpace.CommitChangesSaves all the changes made to the persistent objects belonging to the current Object Space to the database.
The following Controller contains the AddTask Action that creates a new Task object:
File : MySolution.Module\Controllers\TaskViewController.cs.
using DevExpress.ExpressApp;
using DevExpress.ExpressApp.Actions;
using DevExpress.Persistent.Base;
using DevExpress.Persistent.BaseImpl;
// ...
public class TaskViewController : ObjectViewController<ListView, Task> {
public TaskViewController() {
SimpleAction addTaskAction = new SimpleAction(this, "AddTask", PredefinedCategory.Edit);
addTaskAction.Execute += AddTaskAction_Execute;
}
private void AddTaskAction_Execute(object sender, SimpleActionExecuteEventArgs e) {
Task task = ObjectSpace.CreateObject<Task>();
task.Subject = "Demo Task";
View.CollectionSource.Add(task);
ObjectSpace.CommitChanges();
View.Refresh();
}
}
The following Controller contains the AddTask Action that adds a new Task object to the Employee ‘s Tasks collection. This Controller activates for the Employee Detail View and accesses the nested Tasks List View as described in the following topic: How to: Access Nested List View or Master Detail View Environment (ASP.NET Core Blazor and Windows Forms).
File : MySolution.Module\Controllers\EmployeeViewController.cs.
using DevExpress.ExpressApp;
using DevExpress.ExpressApp.Actions;
using DevExpress.Persistent.Base;
using DevExpress.Persistent.BaseImpl;
using DevExpress.ExpressApp.Editors;
// ...
public class EmployeeViewController : ObjectViewController<DetailView, Employee> {
public EmployeeViewController() {
SimpleAction addTaskAction = new SimpleAction(this, "AddTask", PredefinedCategory.Edit);
addTaskAction.Execute += AddTaskAction_Execute;
}
private void AddTaskAction_Execute(object sender, SimpleActionExecuteEventArgs e) {
ListPropertyEditor listPropertyEditor = View.FindItem(nameof(Employee.Tasks)) as ListPropertyEditor;
IObjectSpace os = listPropertyEditor.ListView.ObjectSpace;
Task task = os.CreateObject<Task>();
task.Subject = "Demo Task";
listPropertyEditor.ListView.CollectionSource.Add(task);
os.CommitChanges();
listPropertyEditor.ListView.Refresh();
}
}
In an XPO business class, use the required business class constructor to create a new object and pass the current object’s Session as the constructor parameter. You can do this in the overridden AfterConstruction method.
The following code snippet demonstrates how to initialize Employee ‘s Address1 and Manager reference properties with new and existing objects:
File : MySolution.Module\BusinessObjects\Employee.cs
using DevExpress.Data.Filtering;
using DevExpress.Persistent.BaseImpl;
using DevExpress.Xpo;
// ...
public class Employee : Person {
//...
public override void AfterConstruction() {
base.AfterConstruction();
Address1 = new Address(Session);
Address1.Country = Session.FindObject<Country>(CriteriaOperator.Parse("Name = 'USA'"));
if(Address1.Country == null) {
Address1.Country = new Country(Session);
Address1.Country.Name = "USA";
}
Manager = Session.FindObject<Employee>(CriteriaOperator.Parse(
"FirstName = 'John' && LastName = 'Doe'"));
}
}
IObjectSpaceLink interface and get the ObjectSpace property value.The following code snippet demonstrates how to initialize the Address1 reference property with a new or existing object:
File : MySolution.Module\BusinessObjects\Employee.cs
using DevExpress.Data.Filtering;
using DevExpress.ExpressApp;
using DevExpress.Persistent.Base;
using DevExpress.Persistent.BaseImpl.EF;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace YourSolutionName.Module.BusinessObjects;
[DefaultClassOptions]
public class Employee : IXafEntityObject {
[Key]
public virtual Guid ID { get; set; }
public virtual string Manager { get; set; }
public void OnCreated() {
// ...
var address = ObjectSpace.FindObject<Address>(CriteriaOperator.FromLambda<Address>(a => a.Country == "USA"));
if(address == null) {
address = ObjectSpace.CreateObject<Address>();
address.Country = "USA";
}
Address1 = address;
}
public virtual Address Address1 { get; set; }
public void OnLoaded() { }
public void OnSaving() { }
public IObjectSpace ObjectSpace {
get {
return ((IObjectSpaceLink)this).ObjectSpace;
}
}
}
[DefaultClassOptions]
[DefaultProperty(nameof(Country))]
public class Address : BaseObject {
public virtual string Country { get; set; }
// ...
}
// Make sure that you use options.UseChangeTrackingProxies() in your DbContext settings.
Alternatively, you can inherit your class from the DevExpress.Persistent.BaseImpl.EF.BaseObject class as follows:
using DevExpress.Data.Filtering;
using DevExpress.ExpressApp;
using DevExpress.Persistent.Base;
using DevExpress.Persistent.BaseImpl.EF;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace YourSolutionName.Module.BusinessObjects;
[DefaultClassOptions]
public class Employee : BaseObject {
public virtual string Manager { get; set; }
public override void OnCreated() {
// ...
var address = ObjectSpace.FindObject<Address>(CriteriaOperator.FromLambda<Address>(a => a.Country == "USA"));
if(address == null) {
address = ObjectSpace.CreateObject<Address>();
address.Country = "USA";
}
Address1 = address;
}
public virtual Address Address1 { get; set; }
}
[DefaultClassOptions]
[DefaultProperty(nameof(Country))]
public class Address : BaseObject {
public virtual string Country { get; set; }
// ...
}
// Make sure that you use options.UseChangeTrackingProxies() in your DbContext settings.