Save Big on Cyber Monday! Up to 40% Off
ends in   {{days}}
Days
{{timeFormat.hours}}
:
{{timeFormat.minutes}}
:
{{timeFormat.seconds}}

Connecting C# to Salesforce With Entity Framework Core

Integration of .NET applications with Salesforce CRM often presents unnecessary technical challenges despite Salesforce's robust API. dotConnect for Salesforce solves this problem; it's a specialized ADO.NET data provider with straightforward Entity Framework Core support. This article demonstrates how to quickly set up, connect, and perform CRUD operations with Salesforce data using familiar EF Core patterns.

Why dotConnect for Salesforce

dotConnect for Salesforce is built to simplify integration between .NET applications and Salesforce. It enables application developers to connect to Salesforce directly and perform data-related operations efficiently, handling real-time queries and processing large datasets.

The compatibility with ORM frameworks like Entity Framework also enables developers to simplify all their workflows and work with Salesforce data in an object-oriented way.

Prerequisites

Before you begin, make sure you have the following in place:

  • Visual Studio 2022: The IDE of choice for .NET development. If you don't have it installed, you can download the free Community Edition from the official Microsoft website.
  • dotConnect for Salesforce: A high-performance ADO.NET data provider for Salesforce with enhanced ORM support and flawless database connectivity.
  • Salesforce account: An active Salesforce account with the necessary permissions to access and manage data.

Download and activate dotConnect for Salesforce

30-day free trial version

Download and install dotConnect for Salesforce directly on your computer, or install the Devart.Data.Salesforce NuGet package.

No license key is required; you can start exploring the product immediately.

Full version

After purchasing the full version, go to your profile's Products page. Hover over dotConnect for Salesforce and click Details. Here, you'll find the license details and the activation key.

License details and the activation key.

To activate a connection in your application, specify the activation key in the License Key connection string parameter.

Get the Salesforce security API token

You need the following valid credentials to connect to Salesforce and access the data:

  • User ID
  • Password
  • Security token

To obtain the security token:

1. Sign in to your Salesforce account.

2. Go to your profile and select Settings.

3. Select Reset My Security Token and click Reset Security Token.

The Reset My Security Token page in Salesforce settings.

A new token will be sent to your email. Use this security token for API access when connecting to Salesforce.

Install NuGet packages for a project

First of all, you need to create a project:

1. Open Visual Studio and select Create a new project.

2. Select Console App and click Next.

3. Name your project (our demo project will be SalesforceEFCoreConsoleApp), check other details, and click Create.

Now, you need to install the NuGet package to use dotConnect for Salesforce when creating applications with Visual Studio:

1. Select Tools > NuGet Package Manager > Manage NuGet Packages for Solution.

2. Click Browse, search for Devart.Data.Salesforce.EFCore, and select the matching result.

3. Select your project, then click Install.

View Salesforce data using Server Explorer

1. In Server Explorer, right-click Data Connections and select Add Connection.

The Data Connections shortcut menu in Visual Studio.

The Choose Data Source dialog opens.

2. Under Data source, select Salesforce Data Source.

3. Under Data provider, select dotConnect for Salesforce.

4. Click Continue.

The Choose Data Source dialog.

The Add Connection dialog opens.

5. Fill in the Host, User Id, Password, and Security Token fields with the Salesforce connection parameters.

6. Click Test Connection to verify that the connection settings are correct and that you can connect to Salesforce.

The Add Connection dialog and the nofitication that the test conenction succeeded.

7. In Server Explorer, expand the newly created data connection to view the database structure.

To view the list of tables in the database, expand the Tables node. To view a table's columns, expand the table.

8. To retrieve data from a table, right-click the table name and select Retrieve Data.

The data from the table appears in the new tab.

The data retrieved from the Account table in Visual Studio.

Create an EF Core model

After you have configured the database, you can move on to the next step—creating an EF Core model. You can do this in two ways: using Scaffold-DbContext or via Entity Developer.

Create an EF Core model using Scaffold-DbContext

  1. Ensure the EF Core Tools are installed in your development environment. To install them globally, run this command in the .NET command-line interface:
    dotnet tool install --global dotnet-ef
    
  2. To install Scaffold-DbContext, in Visual Studio, go to Tools > NuGet Package Manager > Package Manager Console and run this command:
    Install-Package Microsoft.EntityFrameworkCore.Tools
    
  3. When the package is installed, you can use Scaffold-DbContext to generate DbContext and entity classes for your Salesforce database. Run the following command in the Package Manager Console, replacing values with your actual credentials:
    Scaffold-DbContext "Authentication Type=UserNamePassword;Host=https://salesforce.com;User Id=user@force.com;Password=**********;Security Token=**********;License Key=**********;" -provider Devart.Data.Salesforce.Entity.EFCore -OutputDir Models
    

The ModelContext file and the Models folder containing the table entity classes are generated and appear in Solution Explorer. This means the migration has been applied, and the DbContext classes have been created.

Create an EF Core model via Entity Developer

Note
If you don't have Entity Developer installed, close your Visual Studio instance and install Entity Developer following the on-screen instructions.

1. Right-click inside Solution Explorer and select Add > New Item.

The expanded Add submenu in the Solution Explorer shortcut menu.

2. Select Installed > C# Items > Data.

3. Select Devart EF Core Model, then click Add.

The Add New Item dialog.

The Create Model Wizard opens.

4. Select Database First, then click Next.

The Welcome page of the Create Model Wizard.

5. Enter the Salesforce connection parameters, then click Next.

The Set up data connection properties page of the Create Model Wizard.

6. Select Generate From Database, then click Next.

The Choose Model Contents page of the Create Model Wizard.

7. Choose the data source objects you want to scaffold. For tutorial purposes, let's select only the Account table. Then click Next.

The Select database objects page of the Create Model Wizard.

8. Define the naming convention for the property names in the data source object, then click Next. We recommend keeping the default settings.

The Set up naming rules page of the Create Model Wizard.

9. Configure the necessary settings for the model. In particular, select the file to save the connection, specify connection string versions, and define the names of DbContext classes. Then, click Next.

The Model properties page of the Create Model Wizard.

10. Choose the model diagram content. You can use all entities, split the entities by database, or customize the selection. For this tutorial, select All Entities, then click Next.

The Choose Model Diagram Contents page of the Create Model Wizard.

11. Choose code generation templates for your objects. You can define parameters according to your preferences or apply default settings. For this tutorial, use the default settings. Click Next.

The Choose Code Generation Templates page of the Create Model Wizard.

Your model is ready now.

12. Click Finish.

The final page of the Create Model Wizard.

The created model opens.

VIsual Studio with the created data model.

Read data from Salesforce

With this setup, you can connect to Salesforce using Entity Framework Core and retrieve data. Use the following code in the Program.cs file to retrieve the first 10 rows from the Account table.

using (var context = new SalesforceModel())
{
  try
  {
    // Check connection status
    var canConnect = context.Database.CanConnect();
    Console.WriteLine($"Connection Status: {(canConnect ? "Connected" : "Not Connected")}");

    if (canConnect)
    {
      // Retrieve the first 10 rows from the Account table
      var accounts = context.Accounts
        .Select(a => new
        {
          a.Id,
          a.Name,
          a.Phone,
          a.Website,
          a.CreatedDate
        })
        .Take(10)
        .ToList();

      // Display the results
      Console.WriteLine("First 10 Accounts:");
      foreach (var account in accounts)
      {
        Console.WriteLine($"Id: {account.Id}, Name: {account.Name}, Phone: {account.Phone}, Website: {account.Website}, CreatedDate: {account.CreatedDate}");
      }
    }
  }
  catch (Exception ex)
  {
    Console.WriteLine($"An error occurred: {ex.Message}");
  }
}

Insert new data into Salesforce

You can modify the Program.cs file to include the insertion logic. For example, let's insert five new records into the Account table with only the Name, Phone, and Website fields populated. Below is the updated code that inserts the records and then retrieves and displays only the inserted records.

using (var context = new SalesforceModel())
{
  try
  {
    // Check connection status
    var canConnect = context.Database.CanConnect();
    Console.WriteLine($"Connection Status: {(canConnect ? "Connected" : "Not Connected")}");

    if (canConnect)
    {
      // Insert 5 new records without setting the Id field
      var newAccounts = new[]
      {
        new Account { Name = "New Account 1", Phone = "123-456-7890", Website = "http://newaccount1.com" },
        new Account { Name = "New Account 2", Phone = "234-567-8901", Website = "http://newaccount2.com" },
        new Account { Name = "New Account 3", Phone = "345-678-9012", Website = "http://newaccount3.com" },
        new Account { Name = "New Account 4", Phone = "456-789-0123", Website = "http://newaccount4.com" },
        new Account { Name = "New Account 5", Phone = "567-890-1234", Website = "http://newaccount5.com" }
      };

      context.Accounts.AddRange(newAccounts);
      int recordsAffected = context.SaveChanges();
      Console.WriteLine($"Records inserted: {recordsAffected}");

      // Retrieve and display the inserted records
      var insertedAccounts = context.Accounts
        .Where(a => newAccounts.Select(na => na.Name).Contains(a.Name))
        .Select(a => new
        {
          a.Id,
          a.Name,
          a.Phone,
          a.Website,
          a.CreatedDate
        })
        .ToList();

      Console.WriteLine("Inserted Accounts:");
      foreach (var account in insertedAccounts)
      {
        Console.WriteLine($"Id: {account.Id}, Name: {account.Name}, Phone: {account.Phone}, Website: {account.Website}, CreatedDate: {account.CreatedDate}");
      }
    }
  }
  catch (Exception ex)
  {
    Console.WriteLine($"An error occurred: {ex.Message}");
  }
}

The code creates an array of five new Account objects with the Name, Phone, and Website fields populated. These are then added to the Accounts DbSet using AddRange, and SaveChanges is called to persist them to the database.

After insertion, the code retrieves the inserted records by matching the Name field. It then displays the Id, Name, Phone, Website, and CreatedDate fields for each inserted record.

The inserted records retrieved in Visual Studio Debug Console.

Update Salesforce data

You can modify the Program.cs file to include the update logic. Say, you want to update existing records in the Account table with new values for the Name, Phone, and Website fields. Below is the updated code that performs the update operation for the specified Id values.

using (var context = new SalesforceModel())
{
  try
  {
    // Check connection status
    var canConnect = context.Database.CanConnect();
    Console.WriteLine($"Connection Status: {(canConnect ? "Connected" : "Not Connected")}");

    if (canConnect)
    {
      // Update existing records
      var accountsToUpdate = new[]
      {
        new { Id = "001WV00000TmQxDYAV", Name = "Updated Account 1", Phone = "987-654-3210", Website = "http://updatedaccount1.com" },
        new { Id = "001WV00000TmQxEYAV", Name = "Updated Account 2", Phone = "876-543-2109", Website = "http://updatedaccount2.com" },
        new { Id = "001WV00000TmQxFYAV", Name = "Updated Account 3", Phone = "765-432-1098", Website = "http://updatedaccount3.com" },
        new { Id = "001WV00000TmQxGYAV", Name = "Updated Account 4", Phone = "654-321-0987", Website = "http://updatedaccount4.com" }
      };

      foreach (var accountData in accountsToUpdate)
      {
        var account = context.Accounts.Find(accountData.Id);
        if (account != null)
        {
          account.Name = accountData.Name;
          account.Phone = accountData.Phone;
          account.Website = accountData.Website;
        }
      }

      context.SaveChanges();

      // Retrieve and display the updated records
      var updatedAccounts = context.Accounts
        .Where(a => accountsToUpdate.Select(au => au.Id).Contains(a.Id))
        .Select(a => new
        {
          a.Id,
          a.Name,
          a.Phone,
          a.Website,
          a.CreatedDate
        })
        .ToList();

      Console.WriteLine("Updated Accounts:");
      foreach (var account in updatedAccounts)
      {
        Console.WriteLine($"Id: {account.Id}, Name: {account.Name}, Phone: {account.Phone}, Website: {account.Website}, CreatedDate: {account.CreatedDate}");
      }
    }
  }
  catch (Exception ex)
  {
    Console.WriteLine($"An error occurred: {ex.Message}");
  }
}

The code defines an array of objects containing the Id values of the records to be updated, along with the new values for Name, Phone, and Website.

For each record, the code uses context.Accounts.Find(accountData.Id) to retrieve the existing record by Id. If the record is found, it updates the Name, Phone, and Website fields with the new values.

context.SaveChanges() is called to persist the updates to the database.

After updating, the code retrieves the updated records and displays the relevant fields.

The updated records displayed in Visual Studio Debug Console.

Delete data from Salesforce

You can modify the Program.cs file to include the deletion logic. Let's delete records with specific Id values from the Account table. Below is the updated code that performs the deletion operation for the specified Id values.

using (var context = new SalesforceModel())
{
  try
  {
    // Check connection status
    var canConnect = context.Database.CanConnect();
    Console.WriteLine($"Connection Status: {(canConnect ? "Connected" : "Not Connected")}");

    if (canConnect)
    {
      // Delete existing records
      var idsToDelete = new[]
      {
        "001WV00000TmQxDYAV",
        "001WV00000TmQxEYAV",
        "001WV00000TmQxFYAV",
        "001WV00000TmQxGYAV"
      };

      var accountsToDelete = context.Accounts
        .Where(a => idsToDelete.Contains(a.Id))
        .ToList();

      context.Accounts.RemoveRange(accountsToDelete);
      context.SaveChanges();

      Console.WriteLine("Records deleted successfully.");
    }
  }
  catch (Exception ex)
  {
    Console.WriteLine($"An error occurred: {ex.Message}");
  }
}

The code defines an array of Id values for the records to be deleted. It retrieves the records with the specified Id values using Where and Contains, then removes them from the Accounts DbSet using RemoveRange.

The message about successful record deletion in Visual Studio Debug Console.

Conclusion

With dotConnect for Salesforce and Entity Framework Core, developers can interact with Salesforce data using the same object-oriented approach they use for traditional databases. This tutorial has shown how to establish connections, create models, and perform essential data operations without the typical complexity of Salesforce integrations. The result is efficient development that effectively handles everything from simple queries to large dataset processing.

dotConnect for Salesforce

Get an enhanced ORM-enabled data provider for Salesforce and develop .NET applications working with Salesforce data quickly and easily!

Discover the ultimate capabilities of dotConnect for Salesforce Download free trial