Skip to content

Instantly share code, notes, and snippets.

@bengavin
Created August 23, 2016 19:06
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save bengavin/e75d5759b4941176b4e51b742428bd15 to your computer and use it in GitHub Desktop.
Save bengavin/e75d5759b4941176b4e51b742428bd15 to your computer and use it in GitHub Desktop.
Example Custom DbSet/DbContext
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Data.Entity;
using System.Data.Entity.Infrastructure;
using System.Linq;
using System.Linq.Expressions;
using System.Threading;
using System.Threading.Tasks;
namespace CustomDbSetSample
{
class Program
{
public static void Main(string[] args)
{
Console.WriteLine("Creating Local Database");
var sample1 = new MySampleEntity { Name = "Sample 1" };
var sample2 = new MySampleEntity { Name = "Sample 2" };
var sample3 = new MySampleEntity { Name = "Other Sample 3" };
using (var myDbContext = new MyDbContext($@"Data Source=(LocalDB)\MSSQLLocalDB;Database=SampleDatabase;Integrated Security=True"))
{
myDbContext.Database.CreateIfNotExists();
// Clean existing samples
myDbContext.Database.ExecuteSqlCommand(@"
IF EXISTS(SELECT 1 FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 'MySampleEntity') BEGIN
exec sp_executesql N'DELETE FROM MySampleEntity';
END ELSE BEGIN
CREATE TABLE [dbo].[MySampleEntity]
(
[Id] UNIQUEIDENTIFIER NOT NULL PRIMARY KEY,
[Name] NVARCHAR(255) NOT NULL
)
END");
// put some entities into the database
myDbContext.SampleEntities.Add(sample1);
myDbContext.SampleEntities.Add(sample2);
myDbContext.SampleEntities.Add(sample3);
myDbContext.SaveChanges();
}
using (var myDbContext = new MyDbContext($@"Data Source=(LocalDB)\MSSQLLocalDB;Database=SampleDatabase;Integrated Security=True"))
{
// Run some queries
var queriedSample1 = myDbContext.SampleEntities.AsNoTracking().FirstOrDefault(s => s.Id == sample1.Id);
Console.WriteLine($"Found Sample 1 ({queriedSample1?.Id == sample1.Id})");
var queriedSamples = myDbContext.SampleEntities.AsNoTracking().Where(s => s.Name.StartsWith("Sample")).ToList();
Console.WriteLine($"Found {queriedSamples.Count} entities starting with 'Sample'");
// Add some more
myDbContext.SampleEntities.Attach(sample1);
myDbContext.SampleEntities.Remove(sample1);
var newSample = myDbContext.SampleEntities.Add(new MySampleEntity { Name = "New Sample" });
myDbContext.SaveChanges();
Console.WriteLine($"Found {myDbContext.SampleEntities.Count(s => s.Name.StartsWith("Sample"))} entities starting with 'Sample'");
Console.WriteLine($"Found New Sample with Id: {myDbContext.SampleEntities.FirstOrDefault(s => s.Name == "New Sample")?.Id}");
}
Console.ReadLine();
}
public class CustomDbSet<TEntity> : DbSet<TEntity>, IDbSet<TEntity>
where TEntity : class
{
private readonly DbSet<TEntity> _internalSet;
public CustomDbSet(DbSet<TEntity> internalSet)
{
_internalSet = internalSet;
}
public override ObservableCollection<TEntity> Local => _internalSet.Local;
IQueryProvider IQueryable.Provider => ((IDbSet<TEntity>)_internalSet).Provider;
Type IQueryable.ElementType => ((IDbSet<TEntity>)_internalSet).ElementType;
Expression IQueryable.Expression => ((IDbSet<TEntity>)_internalSet).Expression;
public override DbQuery<TEntity> AsNoTracking()
{
return _internalSet.AsNoTracking();
}
public override DbQuery<TEntity> Include(string path)
{
return _internalSet.Include(path);
}
public override TEntity Add(TEntity entity)
{
Console.WriteLine("Do fancy bits here");
return _internalSet.Add(entity);
}
public override TEntity Attach(TEntity entity)
{
return _internalSet.Attach(entity);
}
public override TEntity Create()
{
return _internalSet.Create();
}
public override TEntity Find(params object[] keyValues)
{
return _internalSet.Find(keyValues);
}
public override TEntity Remove(TEntity entity)
{
return _internalSet.Remove(entity);
}
public override TDerivedEntity Create<TDerivedEntity>()
{
return _internalSet.Create<TDerivedEntity>();
}
public override IEnumerable<TEntity> AddRange(IEnumerable<TEntity> entities)
{
return _internalSet.AddRange(entities);
}
public override Task<TEntity> FindAsync(params object[] keyValues)
{
return _internalSet.FindAsync(keyValues);
}
public override Task<TEntity> FindAsync(CancellationToken cancellationToken, params object[] keyValues)
{
return _internalSet.FindAsync(cancellationToken, keyValues);
}
}
public class MySampleEntity
{
public MySampleEntity()
{
Id = Guid.NewGuid();
}
public Guid Id { get; set; }
public string Name { get; set; }
}
public class MyDbContext : DbContext
{
public MyDbContext(string connectionString) : base(connectionString)
{
}
public IDbSet<MySampleEntity> SampleEntities { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Conventions.Remove<System.Data.Entity.ModelConfiguration.Conventions.PluralizingTableNameConvention>();
base.OnModelCreating(modelBuilder);
}
public override DbSet<TEntity> Set<TEntity>()
{
return new CustomDbSet<TEntity>(base.Set<TEntity>());
}
}
}
}
@phongbv
Copy link

phongbv commented Aug 29, 2019

A got the error Object reference not set to an instance of an object when executing
var facCurr = (from f in dbContext.FACILITY join c in dbContext.CURRENCY on f.CURRENCY_ID equals c.ID where f.AMND_STATE == "F" select new { f.ID, FAC_AMND_STATE = f.AMND_STATE, f.CURRENCY_ID, CURR_AMNND_STATE = c.AMND_STATE, facColl = (from fc in dbContext.FACILITY_COLLATERAL select new { fc.ID, fc.COLLATERAL_ID }).ToList() }).ToList();
but when I executed split query, I worked.

@bengavin
Copy link
Author

Not sure how to help you there :)

Have you tried converting your query to fluent syntax vs. the inline sql syntax to see if that helps clarify what's going wrong? In the sample above, there's no reason to continuously execute the same query to get the entire list of collateral many times and attach it to each currency record, I suspect there's a missing join in there, or you'd be better off executing the collateral query once and just assigning the resulting collection to each child record.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment