Skip to content

Commit 9542159

Browse files
892709: CRUD support in diagram control
1 parent 5d61645 commit 9542159

File tree

1 file changed

+279
-0
lines changed

1 file changed

+279
-0
lines changed

blazor/diagram/data-binding.md

Lines changed: 279 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1118,7 +1118,286 @@ GraphQL is a query language for APIs with which you can get exactly what you nee
11181118

11191119
You can download a complete working sample from [GitHub](https://github.com/SyncfusionExamples/Blazor-Diagram-Examples/tree/master/UG-Samples/DataBinding/GraphQLAdaptor)
11201120
1121+
## Entity Framework
11211122

1123+
You need to follow the below steps to consume data from the **Entity Framework** in the diagram component.
1124+
1125+
### Create DBContext class
1126+
1127+
The first step is to create a DBContext class called **DataBaseContext** to connect to a Microsoft SQL Server database.
1128+
1129+
```csharp
1130+
using DiagramWithRemoteData.Models;
1131+
using Microsoft.EntityFrameworkCore;
1132+
1133+
namespace DiagramWithRemoteData.Data
1134+
{
1135+
public class DataBaseContext : DbContext
1136+
{
1137+
public DataBaseContext(DbContextOptions<DataBaseContext> options) : base(options)
1138+
{
1139+
}
1140+
1141+
private readonly string _connectionString;
1142+
1143+
public DataBaseContext(string connectionString)
1144+
{
1145+
_connectionString = GetConnectionString(connectionString);
1146+
}
1147+
1148+
public string GetConnectionString(string connection)
1149+
{
1150+
string Path = Environment.CurrentDirectory;
1151+
string[] appPath = Path.Split(new string[] { "bin" }, StringSplitOptions.None);
1152+
Console.WriteLine(appPath);
1153+
connection = connection.Replace("|DataDirectory|/", appPath[0]);
1154+
return connection;
1155+
}
1156+
1157+
public DbSet<Models.Employee> Employees { get; set; }
1158+
}
1159+
}
1160+
```
1161+
1162+
### Creating Web API Controller
1163+
1164+
A Web API Controller has to be created which allows directly directly to consume data from the Entity Framework.
1165+
1166+
```csharp
1167+
using Microsoft.AspNetCore.Mvc;
1168+
using Microsoft.EntityFrameworkCore;
1169+
using System.Threading.Tasks;
1170+
using System.Collections.Generic;
1171+
using DiagramWithRemoteData.Data;
1172+
using DiagramWithRemoteData.Models;
1173+
1174+
namespace DiagramWithRemoteData.Controllers
1175+
{
1176+
[Route("api/[controller]")]
1177+
[ApiController]
1178+
public class DataController : ControllerBase
1179+
{
1180+
private readonly DataBaseContext _context;
1181+
1182+
public DataController(DataBaseContext context)
1183+
{
1184+
_context = context;
1185+
}
1186+
1187+
// GET: api/Data
1188+
[HttpGet]
1189+
public async Task<ActionResult<IEnumerable<Employee>>> GetEmployees()
1190+
{
1191+
return await _context.Employees.ToListAsync();
1192+
}
1193+
1194+
// GET: api/Data/5
1195+
[HttpGet("{id}")]
1196+
public async Task<ActionResult<Employee>> GetEmployee(int id)
1197+
{
1198+
var employee = await _context.Employees.FindAsync(id);
1199+
1200+
if (employee == null)
1201+
{
1202+
return NotFound();
1203+
}
1204+
1205+
return employee;
1206+
}
1207+
1208+
// PUT: api/Data/5
1209+
[HttpPut("{tableName}")]
1210+
public async Task<IActionResult> PutEmployee(string tableName, [FromBody] Employee employee)
1211+
{
1212+
1213+
1214+
_context.Entry(employee).State = EntityState.Modified;
1215+
1216+
try
1217+
{
1218+
await _context.SaveChangesAsync();
1219+
}
1220+
catch (DbUpdateConcurrencyException)
1221+
{
1222+
if (!EmployeeExists(employee.EmployeeID))
1223+
{
1224+
return NotFound();
1225+
}
1226+
else
1227+
{
1228+
throw;
1229+
}
1230+
}
1231+
1232+
return NoContent();
1233+
}
1234+
1235+
// POST: api/Data
1236+
[HttpPost("{tableName}")]
1237+
public async Task<IActionResult> PostEmployee(string tableName, [FromBody] Employee employee)
1238+
{
1239+
_context.Employees.Add(employee);
1240+
await _context.SaveChangesAsync();
1241+
1242+
return CreatedAtAction(nameof(GetEmployee), new { id = employee.EmployeeID }, employee);
1243+
}
1244+
1245+
// DELETE: api/Data/5
1246+
[HttpDelete("{id}")]
1247+
public async Task<IActionResult> DeleteEmployee(int id)
1248+
{
1249+
var employee = await _context.Employees.FindAsync(id);
1250+
if (employee == null)
1251+
{
1252+
return NotFound();
1253+
}
1254+
1255+
_context.Employees.Remove(employee);
1256+
await _context.SaveChangesAsync();
1257+
1258+
return NoContent();
1259+
}
1260+
1261+
private bool EmployeeExists(int id)
1262+
{
1263+
return _context.Employees.Any(e => e.EmployeeID == id);
1264+
}
1265+
}
1266+
}
1267+
1268+
```
1269+
1270+
### Configure diagram component using Web API adaptor
1271+
1272+
Now, you can configure the diagram using the **'SfDataManager'** to interact with the created Web API and consume the data appropriately. To interact with web api, you need to use WebApiAdaptor.
1273+
1274+
```cshtml
1275+
@using Syncfusion.Blazor.Data
1276+
@using Syncfusion.Blazor
1277+
@using Syncfusion.Blazor.Diagram
1278+
@using DiagramWithRemoteData.Controllers
1279+
1280+
<div id="diagram-space" class="content-wrapper">
1281+
<SfDiagramComponent @ref="@diagram" Width="100%" Height="690px" ConnectorCreating="@ConnectorCreating" NodeCreating="@NodeCreating">
1282+
<DataSourceSettings ID="EmployeeID" ParentID="ReportsTo">
1283+
<SfDataManager Url="api/Data" Adaptor="Syncfusion.Blazor.Adaptors.WebApiAdaptor"></SfDataManager>
1284+
</DataSourceSettings>
1285+
<Layout Type="Syncfusion.Blazor.Diagram.LayoutType.HierarchicalTree" VerticalSpacing="75" HorizontalSpacing="75" GetLayoutInfo="GetLayoutInfo"></Layout>
1286+
</SfDiagramComponent>
1287+
1288+
</div>
1289+
@functions{
1290+
SfDiagramComponent? diagram;
1291+
public static List<EmployeeDetails> employeeDetails { get; set; }
1292+
Layout LayoutValue = new Layout() { };
1293+
private TreeInfo GetLayoutInfo(IDiagramObject obj, TreeInfo options)
1294+
{
1295+
options.EnableSubTree = true;
1296+
options.Orientation = Orientation.Horizontal;
1297+
return options;
1298+
}
1299+
private void NodeCreating(IDiagramObject obj)
1300+
{
1301+
Node? node = obj as Node;
1302+
node.Width = 200;
1303+
node.Height = 100;
1304+
Dictionary<string, object> data = node.Data as Dictionary<string, object>;
1305+
if (data != null)
1306+
{
1307+
node.Annotations = new DiagramObjectCollection<ShapeAnnotation>()
1308+
{
1309+
new ShapeAnnotation()
1310+
{
1311+
Content = $"Name:{data["Name"]}\nReportsTo:{data["ReportsTo"]}\nDesignation:{data["Designation"]}",
1312+
}
1313+
};
1314+
}
1315+
}
1316+
private void ConnectorCreating(IDiagramObject connector)
1317+
{
1318+
Connector? newConnector = connector as Connector;
1319+
newConnector!.TargetDecorator = new DecoratorSettings() { Shape = DecoratorShape.None };
1320+
newConnector.Type = ConnectorSegmentType.Orthogonal;
1321+
newConnector.Style = new ShapeStyle() { StrokeColor = "#6d6d6d" };
1322+
newConnector.Constraints = ConnectorConstraints.None;
1323+
newConnector.CornerRadius = 5;
1324+
}
1325+
1326+
public class EmployeeDetails
1327+
{
1328+
public int EmployeeID { get; set; }
1329+
1330+
public string ReportsTo { get; set; }
1331+
1332+
public string Name { get; set; }
1333+
1334+
public string Designation { get; set; }
1335+
1336+
public string Colour { get; set; }
1337+
}
1338+
}
1339+
```
1340+
1341+
### CRUD
1342+
The SfDiagramComponent supports CRUD (Create, Read, Update, Delete) operations using SfDataManager for remote data management. By making API calls to update data, the diagram automatically rerenders, ensuring real-time synchronization between the front-end diagram and the backend. This allows users to manage and manipulate diagram data from remote databases or APIs using methods like ReadData, UpdateData, InsertData, and DeleteData.
1343+
1344+
### Read DataSource
1345+
The SfDiagramComponent can fetch and display data from remote sources using the ReadDataAsync method. This method retrieves data from the server that we visualized as nodes and connectors in the diagram. This method is invoked when the user wants to load the raw data from the server.
1346+
```csharp
1347+
//To fetch data from the remote service
1348+
public async void Read()
1349+
{
1350+
var data = await diagram.ReadDataAsync();
1351+
}
1352+
```
1353+
1354+
### Updating Existing Data
1355+
The UpdateDataAsync method updates the data on the remote server through an API call. Once the data is updated, the diagram automatically refreshes and displays the latest data from the server.
1356+
```csharp
1357+
//To update data in the remote service
1358+
public async void Update()
1359+
{
1360+
EmployeeDetails employeeDetails = new EmployeeDetails()
1361+
{
1362+
EmployeeID = 6,
1363+
Name = "Michael",
1364+
Designation = "Product Manager",
1365+
ReportsTo = "1",
1366+
Colour = "Green"
1367+
};
1368+
await diagram.UpdateDataAsync("EmployeeID", employeeDetails);
1369+
}
1370+
```
1371+
1372+
### Inserting New Data
1373+
The InsertDataAsync method adds new data to the remote server via an API. Once the data is inserted, the diagram updates itself to include the new nodes and connectors.
1374+
```csharp
1375+
//To push data to the remote service
1376+
public async void Insert()
1377+
{
1378+
EmployeeDetails employeeDetails = new EmployeeDetails()
1379+
{
1380+
EmployeeID = 11,
1381+
Name = "Alan",
1382+
Designation = "HR assistant",
1383+
ReportsTo = "9",
1384+
Colour = "Gray"
1385+
};
1386+
await diagram.InsertDataAsync(employeeDetails);
1387+
}
1388+
```
1389+
1390+
### Deleting Data
1391+
The DeleteDataAsync method removes data from the remote server. Once the data is deleted, the diagram refreshes itself to reflect the removal of nodes and connectors.
1392+
```csharp
1393+
//To delete data in the remote service
1394+
public async void Delete()
1395+
{
1396+
await diagram.DeleteDataAsync("EmployeeID", 5);
1397+
}
1398+
```
1399+
1400+
You can find the fully working sample here.
11221401
## See Also
11231402

11241403
* [How to arrange the diagram nodes and connectors using varies layout](./layout/automatic-layout)

0 commit comments

Comments
 (0)