Using IQueryable <TEntity> instead of DbSet <TEntity>

I came across the following problem ... I have a database context:

// For support unit testing... public interface IDbContext : IDisposable { IQueryable<Hardware> Hardwares { get; } IQueryable<ProviderHardware> ProviderHardwares { get; } } // Real DbContext (EF 4.0, Code First) public class PrimaryDbContext : DbContext, IDbContext { public DbSet<Hardware> Hardwares { get; set; } public DbSet<ProviderHardware> ProviderHardwares { get; set; } IQueryable<Hardware> IDbContext.Hardwares { get { return Hardwares; } } IQueryable<ProviderHardware> IDbContext.ProviderHardwares { get { return ProviderHardwares; } } ... } 

And I'm trying to get all the hardware that is not in the ProviderHardwares table:

 var hardwaresRemoved = db.Hardwares.Where(i => (i.IsAvailable == true) && (db.ProviderHardwares.Count(j => j.Article == i.Article) == 0)).ToList(); 

If I use PrimaryDbContext strictly, for example, PrimaryDbContext db = new PrimaryDbContext (); "everything works well. But if I use it implicitly" IDbContext db = new PrimaryDbContext (); "that I get an exception:

It is not possible to create a constant value of type 'ConfiguratorMvcApplication.DomainModels.ProviderHardware. Only primitive types (such as Int32, String, and Guid) are supported in this context.

To summarize, I cannot replace DbSet with IQueryable. And how can I use unit testing in this case? I hope someone else resolves this issue more ... Thank you in advance!

+6
source share
2 answers

I suggest you better keep DbSets and INTEGRATION TESTING , including the database.

Because, although passing a unit test with a database layout can be somewhat useful, you will be better off testing the real database (but this is not unit testing).

In ClassInitialize, delete the database and / or create the source data for testing.

If you create an App.config file with a connection string, you can have a separate test database, and if you use EF Code First, you will get it for free.

Sincerely.

-2
source

In the end, I had two properties for each DbSet: one of the IQueryable types and one of the DbSet types. The IQueryable property is defined in the interface, and it passes calls to a specific implementation (a property of type DbSet) as follows:

 // Exists in the interface public IQueryable<AccountContact> AccountContacts { get { return DbAccountContacts; } set { DbAccountContacts = (DbSet<AccountContact>)value; } } // Exists only in the implementation public DbSet<AccountContact> DbAccountContacts { get; set; } 

After this setup, I was able to make fun of it normally and could unit test code.

It is definitely too late for the OP, but perhaps it helps someone who is struggling with the same issue as me.

+1
source

Source: https://habr.com/ru/post/895536/


All Articles