Entity Framework - 2.2

Extension ID

com.castsoftware.entity

What’s new?

See Entity Framework 2.2 - Release Notes for more information.

Description

This extension provides support for Entity Framework. The calculation of Automated Function Points for your .NET analyses will be supplemented through the links between objects produced by the base .NET Analyzer and database tables, using Entity Framework CRUD operations.

In what situation should you install this extension?

If your .NET application contains Entity Framework source code and you want to view these object types and their links, then you should install this extension. More specifically the extension will identify:

  • “call” links from C# methods using Entity Framework operations to Entity framework operation objects
  • “use” links from Entity framework operation objects to participating Database tables

Technology support

The following .NET framework / Libraries are supported by this extension:

Framework / Library name Version Supported Supported Technology Comments
Entity Framework (EF, EF6) 3.0 to 6.4.x ✔️ C#
Entity Framework Core (EF Core) 1.0.x to 7.0.x ✔️ C#
Z.EntityFramework.Plus.EF6 1.6.4 to 7.21.0 ✔️ C# Entity Framework Plus extends DbContext with must-have features: Include Filter, Auditing, Caching, Query Future, Batch Delete and Batch Update.
Z.EntityFramework.Plus.EFCore 2.22.3 to 7.22.4 ✔️ C# Same as above
EFCore.BulkExtensions 1.0 to 7.1 ✔️ C#
LINQ to Entities - method syntax ✔️ C#

Function Point, Quality and Sizing support

This extension provides the following support:

  • Function Points (transactions): a green tick indicates that OMG Function Point counting and Transaction Risk Index are supported
  • Quality and Sizing: a green tick indicates that CAST can measure size and that a minimum set of Quality Rules exist
Function Points (transactions) Quality and Sizing
✔️ ✔️

Compatibility

CAST Imaging Core release Supported
8.3.x ✔️

Download and installation instructions

The extension will be automatically downloaded and installed in CAST Console. You can manage the extension using the Application - Extensions interface.

What results can you expect?

Objects

Icon Object Type Description Comment
EF Entity Created when the DbSet Entity is declared in the derived class inheriting from DbContext
EF Entity Operation Used when CRUD operation is performed on Entity
EF SQL Query Used for native queries
EF Unknown SQL Query Used when the query could not be resolved
EF Unknown Entity Created and used when the entity could not be resolved
EF Unknown Entity Operation Used when CRUD operation is performed and Entity could not be resolved
Link type Source and destination of link  Methods supported

callLink 

useInsertLink

callLink between the caller .NET Method object and EF Entity Operation /EF Unknown Entity Operation object

useInsertLink between the EF Entity Operation object and Database Table object

    EF Insert Operation APIs
  • System.Data.Entity.DbSet.Add
  • System.Data.Entity.DbSet.AddRange
    EF Core DbSet & DbContext Insert Operation APIs
  • Microsoft.EntityFrameworkCore.DbSet.Add
  • Microsoft.EntityFrameworkCore.DbSet.AddRange
  • Microsoft.EntityFrameworkCore.DbSet.AddAysnc
  • Microsoft.EntityFrameworkCore.DbSet.AddRangeAsync
  • Microsoft.EntityFrameworkCore.DbContext.AddRange
  • Microsoft.EntityFrameworkCore.DbContext.AddRangeAsync
  • Microsoft.EntityFrameworkCore.DbContext.Add
  • Microsoft.EntityFrameworkCore.DbContext.AddAsync
    Insert Operation supported through ObjectContext APIs
  • System.Data.Objects.ObjectContext.AddObject
  • System.Data.Objects.ObjectSet.AddObject
  • System.Data.Entity.Core.Objects.ObjectContext.AddObject
    Insert Operation through EFCore.BulkExtensions
  • EFCore.BulkExtensions.DbContextBulkExtensions.BulkInsert
  • EFCore.BulkExtensions.DbContextBulkExtensions.BulkInsertAsync
  • EFCore.BulkExtensions.DbContextBulkExtensions.BulkInsertOrUpdate
  • EFCore.BulkExtensions.DbContextBulkExtensions.BulkInsertOrUpdateAsync
  • EFCore.BulkExtensions.DbContextBulkExtensions.BulkInsertOrUpdateOrDeleteAsync
  • EFCore.BulkExtensions.DbContextBulkExtensions.BulkInsertOrUpdateOrDelete

callLink 

useDeleteLink

callLink between the caller .NET Method object and EF Entity Operation / EF Unknown Entity Operation object

useDeleteLink between the EF Entity Operation object and Database Table object

    EF Delete Operation APIs
  • System.Data.Entity.DbSet.Remove
  • System.Data.Entity.DbSet.RemoveRange
    EF Core DbSet & DbContext Delete Operation APIs
  • Microsoft.EntityFrameworkCore.DbSet.Remove
  • Microsoft.EntityFrameworkCore.DbSet.RemoveRange
  • Microsoft.EntityFrameworkCore.DbContext.Remove
    Delete Operation supported through ObjectContext APIs
  • System.Data.Objects.ObjectContext.DeleteObject
  • System.Data.Objects.ObjectSet.DeleteObject
  • System.Data.Entity.Core.Objects.ObjectContext.DeleteObject
    Delete Operations supported through EF Plus APIs
  • Z.EntityFramework.Plus.BatchDeleteExtensions.Delete
    Delete Operation through EFCore.BulkExtensions
  • EFCore.BulkExtensions.DbContextBulkExtensions.BulkDelete
  • EFCore.BulkExtensions.DbContextBulkExtensions.BulkDeleteAsync
  • EFCore.BulkExtensions.DbContextBulkExtensions.BulkInsertOrUpdateOrDelete
  • EFCore.BulkExtensions.DbContextBulkExtensions.BulkInsertOrUpdateOrDeleteAsync
  • EFCore.BulkExtensions.IQueryableBatchExtensions.BatchDelete
  • EFCore.BulkExtensions.IQueryableBatchExtensions.BatchDeleteAsync

callLink 

useUpdateLink

callLink between the caller .NET Method object and EF Entity Operation /EF Unknown Entity Operation object

useUpdateLink between the EF Entity Operation object and Database Table object

    EF Core DbSet & DbContext Update Operation APIs
  • Microsoft.EntityFrameworkCore.DbSet.Update
  • Microsoft.EntityFrameworkCore.DbSet.UpdateRange
  • Microsoft.EntityFrameworkCore.DbContext.Update
    Update Operations supported through EF Plus APIs
  • Z.EntityFramework.Plus.BatchUpdateExtensions.Update
    Update Operation through EFCore.BulkExtensions
  • EFCore.BulkExtensions.DbContextBulkExtensions.BulkUpdate
  • EFCore.BulkExtensions.DbContextBulkExtensions.BulkUpdateAsync
  • EFCore.BulkExtensions.DbContextBulkExtensions.BulkInsertOrUpdate
  • EFCore.BulkExtensions.DbContextBulkExtensions.BulkInsertOrUpdateAsync
  • EFCore.BulkExtensions.DbContextBulkExtensions.BulkInsertOrUpdateOrDelete
  • EFCore.BulkExtensions.DbContextBulkExtensions.BulkInsertOrUpdateOrDeleteAsync
  • EFCore.BulkExtensions.IQueryableBatchExtensions.BatchUpdate
  • EFCore.BulkExtensions.IQueryableBatchExtensions.BatchUpdateAsync

callLink 

useSelectLink

callLink between the caller .NET Method object and EF Entity Operation / EF Unknown Entity Operation object

useSelecttLink between the EF Entity Operation object and Database Table object

    EF Select Operation APIs
  • System.Data.Entity.DbSet.Attach
  • System.Data.Entity.DbSet.Create
  • System.Data.Entity.DbSet.Equals
  • System.Data.Entity.DbSet.Find
  • System.Data.Entity.DbSet.FindAsync
  • System.Data.Entity.DbSet.GetHashCode
  • System.Data.Entity.DbSet.GetType
  • System.Data.Entity.DbSet.Include
  • System.Data.Entity.DbSet.SqlQuery
  • System.Data.Entity.DbSet.ToString
  • System.Data.Entity.QueryableExtensions.AllAsync
  • System.Data.Entity.QueryableExtensions.AnyAync
  • System.Data.Entity.QueryableExtensions.AverageAsync
  • System.Data.Entity.QueryableExtensions.AsNoTracking
  • System.Data.Entity.QueryableExtensions.AsTracking
  • System.Data.Entity.QueryableExtensions.Contains
  • System.Data.Entity.QueryableExtensions.CountAsync
  • System.Data.Entity.QueryableExtensions.FirstAsync
  • System.Data.Entity.QueryableExtensions.FirstOrDefaultAsync
  • System.Data.Entity.QueryableExtensions.ForEachAsync
  • System.Data.Entity.QueryableExtensions.Include
  • System.Data.Entity.QueryableExtensions.Load
  • System.Data.Entity.QueryableExtensions.LoadAsync
  • System.Data.Entity.QueryableExtensions.LongCountAsync
  • System.Data.Entity.QueryableExtensions.MaxAsync
  • System.Data.Entity.QueryableExtensions.MinAsync
  • System.Data.Entity.QueryableExtensions.SingleAsync
  • System.Data.Entity.QueryableExtensions.SingleOrDefaultAsync
  • System.Data.Entity.QueryableExtensions.SumAsync
  • System.Data.Entity.QueryableExtensions.ToArrayAsync
  • System.Data.Entity.QueryableExtensions.ToDictionaryAsync
  • System.Data.Entity.QueryableExtensions.ToListAsync
  • Immediate apis belonging to System.Linq.Enumerable
  • Immediate apis belonging to System.Linq.Queryable.


    EF Core Select Operation APIs
  • Microsoft.EntityFrameworkCore.DbSet.Find
  • Microsoft.EntityFrameworkCore.DbSet.FindAsync
  • Microsoft.EntityFrameworkCore.DbSet.GetAsyncEnumerator
  • Microsoft.EntityFrameworkCore.DbSet.GetHashCode
  • Microsoft.EntityFrameworkCore.DbSet.ToString
  • Microsoft.EntityFrameworkCore.DbSet.Equals
  • Microsoft.EntityFrameworkCore.DbSet.Attach
  • Microsoft.EntityFrameworkCore.DbSet.AttachRange
  • Microsoft.EntityFrameworkCore.DbSet.AsQueryable
  • Microsoft.EntityFrameworkCore.DbSet.AsAsyncEnumerable
    Microsft.EntityFrameworkCore.EntityFrameworkQueryableExtensions Select Operation APIs
  • Microsoft.EntityFrameworkCore.EntityFrameworkQueryableExtensions.AllAsync
  • Microsoft.EntityFrameworkCore.EntityFrameworkQueryableExtensions.AnyAsync
  • Microsoft.EntityFrameworkCore.EntityFrameworkQueryableExtensions.AsAsyncEnumerable
  • Microsoft.EntityFrameworkCore.EntityFrameworkQueryableExtensions.AsNoTracking
  • Microsoft.EntityFrameworkCore.EntityFrameworkQueryableExtensions.AsNoTrackingWithIdentityResolution
  • Microsoft.EntityFrameworkCore.EntityFrameworkQueryableExtensions.AsTracking
  • Microsoft.EntityFrameworkCore.EntityFrameworkQueryableExtensions.AverageAsync
  • Microsoft.EntityFrameworkCore.EntityFrameworkQueryableExtensions.ContainsAsync
  • Microsoft.EntityFrameworkCore.EntityFrameworkQueryableExtensions.FirstAsync
  • Microsoft.EntityFrameworkCore.EntityFrameworkQueryableExtensions.FirstOrDefaultAsync
  • Microsoft.EntityFrameworkCore.EntityFrameworkQueryableExtensions.ForEachAsync
  • Microsoft.EntityFrameworkCore.EntityFrameworkQueryableExtensions.IgnoreAutoIncludes
  • Microsoft.EntityFrameworkCore.EntityFrameworkQueryableExtensions.IgnoreQueryFilters
  • Microsoft.EntityFrameworkCore.EntityFrameworkQueryableExtensions.Include
  • Microsoft.EntityFrameworkCore.EntityFrameworkQueryableExtensions.LastAsync
  • Microsoft.EntityFrameworkCore.EntityFrameworkQueryableExtensions.LastOrDefaultAsync
  • Microsoft.EntityFrameworkCore.EntityFrameworkQueryableExtensions.Load
  • Microsoft.EntityFrameworkCore.EntityFrameworkQueryableExtensions.LongCountAsync
  • Microsoft.EntityFrameworkCore.EntityFrameworkQueryableExtensions.MaxAsync
  • Microsoft.EntityFrameworkCore.EntityFrameworkQueryableExtensions.MinAsync
  • Microsoft.EntityFrameworkCore.EntityFrameworkQueryableExtensions.NotQuiteInclude
  • Microsoft.EntityFrameworkCore.EntityFrameworkQueryableExtensions.SingleAsync
  • Microsoft.EntityFrameworkCore.EntityFrameworkQueryableExtensions.SingleOrDefaultAsync
  • Microsoft.EntityFrameworkCore.EntityFrameworkQueryableExtensions.SumAsync
  • Microsoft.EntityFrameworkCore.EntityFrameworkQueryableExtensions.TagWith
  • Microsoft.EntityFrameworkCore.EntityFrameworkQueryableExtensions.TagWithCallSite
  • Microsoft.EntityFrameworkCore.EntityFrameworkQueryableExtensions.ThenInclude
  • Microsoft.EntityFrameworkCore.EntityFrameworkQueryableExtensions.ToArrayAsync
  • Microsoft.EntityFrameworkCore.EntityFrameworkQueryableExtensions.ToDictionaryAsync
  • Microsoft.EntityFrameworkCore.EntityFrameworkQueryableExtensions.ToListAsync
  • Microsoft.EntityFrameworkCore.EntityFrameworkQueryableExtensions.ToQueryAsync
    Z.EntityFramework.Plus Select Operation APIs
  • Z.EntityFramework.Plus.QueryFutureExtensions.FutureValue
  • Z.EntityFramework.Plus.QueryFutureExtensions.Future
  • Z.EntityFramework.Plus.QueryCacheExtensions.FromCache
  • Z.EntityFramework.Plus.QueryCacheExtensions.FromCacheAsync
  • Z.EntityFramework.Plus.QueryDeferred.Execute
  • Z.EntityFramework.Plus.QueryIncludeFilterExtensions.IncludeFilter
  • Z.EntityFramework.Plus.QueryIncludeFilterExtensions.IncludeFilterByPath
  • Z.EntityFramework.Plus.QueryIncludeFilterExtensions.IncludeOptimizedSingle
  • Z.EntityFramework.Plus.QueryIncludeOptimizedExtensions.IncludeOptimized
  • Z.EntityFramework.Plus.QueryIncludeOptimizedExtensions.IncludeOptimizedByPath
  • Z.EntityFramework.Plus.QueryIncludeOptimizedExtensions.IncludeOptimizedSingle
  • Z.EntityFramework.Plus.QueryIncludeOptimizedExtensions.IncludeOptimizedSingleLazy
    Select Operations in EF Plus supported through Eval-Expression.Net Library
  • Immediate apis belonging to System.Linq.QueryableDynamic
  • Immediate apis belonging to System.Linq.EnumerableDynamic
    Select Operation through EFCore.BulkExtensions
  • EFCore.BulkExtensions.DbContextBulkExtensions.BulkRead
  • EFCore.BulkExtensions.DbContextBulkExtensions.BulkReadAsync
callLink callLink between the caller .NET Method object and EF SQL Query / EF Unknown SQl Query object
    Execute APIs
  • System.Data.Entity.Database.ExecuteSqlCommand
  • System.Data.Entity.Database.ExecuteSqlCommandAsync
  • Microsoft.EntityFrameworkCore.RelationalDatabaseFacadeExtensions.ExecuteSqlCommand
  • Microsoft.EntityFrameworkCore.RelationalDatabaseFacadeExtensions.ExecuteSqlCommandAsync
  • Microsoft.EntityFrameworkCore.RelationalDatabaseFacadeExtensions.ExecuteSqlRaw
  • Microsoft.EntityFrameworkCore.RelationalDatabaseFacadeExtensions.ExecuteSqlRawAsync
  • Microsoft.EntityFrameworkCore.RelationalQueryableExtensions.FromSql
  • Microsoft.EntityFrameworkCore.RelationalQueryableExtensions.FromSqlRaw
  • Microsoft.EntityFrameworkCore.RelationalQueryableExtensions.FromSqlInterpolated
    Execute APIs supported through ObjectContext APIs
  • System.Data.Objects.ObjectContext.ExecuteFunction
  • System.Data.Objects.ObjectContext.ExecuteStoreCommand
  • System.Data.Objects.ObjectContext.ExecuteStoreQuery
  • System.Data.Entity.Core.Objects.ObjectContext.ExecuteFunction
  • System.Data.Entity.Core.Objects.ObjectContext.ExecuteStoreCommand
  • System.Data.Entity.Core.Objects.ObjectContext.ExecuteStoreQuery
  • System.Data.Entity.Core.Objects.ObjectContext.ExecuteStoreCommandAsync
  • System.Data.Entity.Core.Objects.ObjectContext.ExecuteStoreQueryAsync

Code examples

Insert operation

Insert operation

Add

public static void GenerateData()
{
    using EntityContext context = new();
    context.Customers.Add(new Customer() { Name = "Customer_A", Description = "Description", IsActive = true });
}

Insert Operation through dbcontext.Set<T>

Insert through dbcontext.Set

public void SaveCalculatedCycles(string discriminator, IEnumerable<AuditCycle> calculatedCycles)
        {
            foreach (AuditCycle cycle in calculatedCycles)
            {
                MissionAuditCycle saveableCycle = new MissionAuditCycle
                {
                    DateOfEarliestAuditPerformed = cycle.DateOfEarliestAuditPerformed,
                    StartDate = cycle.StartDate,
                    EndDate = cycle.EndDate,
                    MissionDiscriminatorWithoutIndex = discriminator,
                    ShiftId = cycle.ShiftId
                };
                _dbContext.Set<MissionAuditCycle>().Add(saveableCycle);
            }
        }

Insert Operation through ObjectContext

Insert Operation through ObjectContext

public void AddToACCESS_RIGHT_STATUS(ACCESS_RIGHT_STATUS aCCESS_RIGHT_STATUS)
{
    base.AddObject("ACCESS_RIGHT_STATUS", aCCESS_RIGHT_STATUS);
}

Delete operation

Delete operation

Delete

public override void DeleteEntity(Entities context, object entity)
        {
            var entityToRemove = (ShelfInspectionCreationPermission)entity;
            if (entityToRemove.AdditionApprovalId != null) { context.AdditionApprovals.Remove(entityToRemove.AdditionApproval); }
            if (entityToRemove.DeletionApprovalId != null) { context.DeletionApprovals.Remove(entityToRemove.DeletionApproval); }

            entityToRemove.User_Depots.ToList().ForEach(ud => ud.ShelfInspectionCreationPermission = null);
            context.ShelfInspectionCreationPermissions.Remove(entityToRemove);
        }

Delete Operation through ObjectContext

Delete Operation through ObjectContext

public void DeleteACCESS_RIGHT_STATUS(ACCESS_RIGHT_STATUS aCCESS_RIGHT_STATUS)
{
    base.DeleteObject(aCCESS_RIGHT_STATUS);
}

Batch Delete Operation through EF Plus

Delete Operation through EF Plus

public override void DeleteEntity(Entities context, object entity)
        {
            var entityToRemove = (Role_SupplierComplaints_ProcessingStage)entity;
            if (entityToRemove.AdditionApprovalId != null) { context.AdditionApprovals.Remove(entityToRemove.AdditionApproval); }
            if (entityToRemove.DeletionApprovalId != null) { context.DeletionApprovals.Remove(entityToRemove.DeletionApproval); }
            context.Role_SupplierComplaints_ProcessingStage.Remove(entityToRemove);
        }

Update Operation

Update operation

Update

public void UpdateContractorAddress()        
{
            var contractor = dbContext.Contractor.FirstOrDefault();
            contractor.Address = ModelFakes.ContractorFake.Generate().Address;
            dbContext.Contractor.Update(contractor);
            dbContext.SaveChanges();
}         

Batch Update Operation through EF Plus

Batch Update Operation through EF Plus

public static void UpdateRows()
{
            
    EntityContext context = new ();
            
    context.Customers.Where(x => x.Name == "Customer_C").Update(x => new Customer {Description = "Updated_C",IsActive = false});
}

Bulk Operations through EFCore.BulkExtensions

Bulk Operations

public static void BulkOperations()
    {
        List<InvoiceItem> invoiceDetails = new List<InvoiceItem>
        {
            new InvoiceItem { InvoiceItemId = 1, ProductName ="Apple" },
            new InvoiceItem { InvoiceItemId = 2, ProductName = "Orange"},
            // Add more invoice details to synchronize
        };
        
        var context = new EntityContext();
        context.BulkInsertOrUpdateOrDelete(invoiceDetails);
     }

Select operation

Select operation

Find

protected void AssignPermissionToUser(User user, int depotId, Entities context)
{
    var user_depotEntity = context.User_Depots.Find(user.Id, depotId);

    if (user_depotEntity.ShelfInspectionCreationPermission != null)
    {
        throw new EntityConflictException("Permission already existing or pending.");
    }

}

Select operation through Z.EntityFramework.Plus

Select

public static void QueryDeferredTrial()
{
    using EntityContext context = new();
        
    //Query Cache
    context.Customers.DeferredCount().FromCache();

}       
        

LINQ-To-Entities

LINQ-To-Entities

LINQ-To-Entities

public string[] GetColumnPermissionsOfUser(int id, string tableName)
{
    using (var context = new Entities())
    {
        List<int> userRoles = context.User_Roles
        .Where(ur => ur.UserId == id)
        .Where(ur => ur.AdditionApproval.ApprovedAt.HasValue)
        .Where(ur => ur.Role.AdditionApproval.ApprovedAt.HasValue)
        .Select(ur => ur.RoleId)
        .ToList();

    }
}

Support for EntityModelConfiguration

EntityModelConfiguration allows configuration to be performed for any entity type in a model. Support has be been provided to create callLink between method and entity operation object and appropriate crud link between entity operation object and table,  when table name is overridden through EntityModelConfiguration.

EntityModelConfiguration

public DomainModel.Portaalstatus OpslaanLogin(Account account)        
{
            using (new LoggingMonitoredScope(LogConstants.Diagnostics))
            {
                ValidationHelper.Validate(account);
                if (ClaimHelper.IsMeekijker())
                    return new DomainModel.Portaalstatus();
                var cacheKey = CacheSettingsHelper.CreateCacheKey(account);
                                _cacheHelper.Remove(cacheKey, CacheGroups.CacheGroupPortaalStatussen);
                DomainModel.Portaalstatus cacheItem;
                using (var dbContext = new ApfPortalenDbContext())
                {
                    var portaalstatus =
                        dbContext.Portaalstatussen.FirstOrDefault(
                            p => p.AdministratieId.Equals(account.AdministratieIdentificatie) &&
                                 p.RelatienummerDeelnemerMaia.Equals(account.RelatienummerDeelnemerMAIA));
            if (portaalstatus == null)
                    {
                        portaalstatus = dbContext.Portaalstatussen.Add(new Portaalstatus());
            }
        }; 
                   
}

Support for CRUD operations using dbContext 

CRUD using dbcontext

public async Task<IActionResult> Create(Distribution distribution)
        {
            if (ModelState.IsValid)
            {
                context.Add(distribution);
                await context.SaveChangesAsync();

                return RedirectToAction("Index");
            }
            else
                return View();
        }

Support for ExecuteSqlQuery

ExecuteSqlCommand

protected void InsertInfo(List<DispatcherInfo> entities)
        {
            int chunkSize = 1000;
            var pendingBar = new PendingBar(Logger);
            pendingBar.Start();

            Entities context = new Entities();

            try
            {
                entities.GroupBy(e => e.DepotId).ToList().ForEach(g =>
                {
                    context.Database.ExecuteSqlCommand("DELETE FROM DispatcherInfoes WHERE DepotId = {0}", g.Key);
                    context.BulkInsert(g.ToList(), chunkSize);
                    context.SaveChanges();
                });
            }
            catch (Exception)
            {
                throw;
            }
            finally
            {
                pendingBar.Stop();
                if (context != null)
                    context.Dispose();
            }
        }
    }

Use of FromSql, FromSqlRaw, FromSqlInterpoated, ExecuteFunction, ExecuteStoreCommand, ExecuteStoryQuery, ExecuteStoreCommand, ExecuteSqlCommand and their Asynchronous counterpart results in the similar transaction as above.

Unknown SQL Query

protected void ResetWorkflowProgress(Entities context, DealerComplaint complaint)
        {
            context.Database.ExecuteSqlCommand(abcd);
            complaint.LastDeciderName = null;
            complaint.LastDecisionDate = null;
        }

Reading of edmx file

edmx file mapping

internal void AddDataChangeApprover(DataChangeApprover dca)
        {
            _context.DataChangeApprovers.Add(dca);
        }

DbContext and DbSet

public partial class DisplayConfigEntities : DbContext
    {
        public DisplayConfigEntities()
            : base("name=DisplayConfigEntities")
        {
        }
    
        protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
            throw new UnintentionalCodeFirstException();
        }
    
        public virtual DbSet<DataChangeApprover> DataChangeApprovers { get; set; }
}

edmx

<EntitySetMapping Name="DataChangeApprovers">
            <EntityTypeMapping TypeName="DispalyConfiguration.DataChangeApprover">
              <MappingFragment StoreEntitySet="Approval">

Support for Table Per Hierarchy

Table Per Hierarchy

public class AppDbContext : DbContext
    {
        public DbSet<CreditCard> CreditCard { get; set; }


        public AppDbContext(DbContextOptions<AppDbContext> options) : base(options) { }

        protected override void OnModelCreating(ModelBuilder modelBuilder)
        {
            modelBuilder.Entity<BillingDetail>().ToTable("BankingBillingDetails");
        }
    }


    public abstract class BillingDetail
    {
        [Required]
        public int BillingDetailId { get; set; } 
        public string Owner { get; set; } 
        public string Number { get; set; } 
    }

    public class CreditCard : BillingDetail
    {
        public int CardType { get; set; }   
        public string ExpiryMonth { get; set; } 
        public string ExpiryYear { get; set; } 
    }

Unknown Entity

Unknown Entity

public class BaseRepository<TEntity> : IRepository<TEntity>
      where TEntity : class
    {
        private WP2AlertsContext alertsContext;

        public BaseRepository(WP2AlertsContext wP2Context)
        {
            alertsContext = wP2Context;
        }

        public virtual async Task<TEntity> AddAsync(TEntity entity)
        {
            await alertsContext.AddAsync(entity);
            alertsContext.Entry(entity).State = EntityState.Added;
            await alertsContext.SaveChangesAsync();
            return entity;
        }
    }

Assumptions

  • SaveChanges() method of DbContext class commits the operation in the database table. Hence no useLink is created between caller method and table.

Limitations

  • Analyzing the participating database tables is mandatory for the extension to produce appropriate useLinks

  • LINQ-Entity Query syntax is not supported

  • Unknown Entity object gets created in case the entity in the CRUD transaction does not get resolved. In such a case, the caller method will get connected to the Unknown Entity Operation object of the Unknown Entity.

  • Unknown SQL Query object gets created if the query used in the execution does not get resolved.