When querying SQL with EF6 from a WebJob, query fails because it's trying to get a pluralized version of the table - entity-framework-6

My code looks like this:
public static void DoSomething(TextWriter log)
{
log.WriteLine("Hey man! I'm running!");
try
{
using (MyDBContext context = new MyDBContext())
{
MemberMaster mm = context.MemberMaster.SingleOrDefault(m => m.MemberMasterId == 1);
if (mm != null)
{
log.WriteLine(string.Format("MemberMasterId = {0}, Username = {1}", mm.MemberMasterId, mm.UserName));
}
else
{
log.WriteLine("Could not find Member with MembermasterId = 1");
}
}
}
catch (Exception ex)
{
log.WriteLine(ex.Message);
}
log.WriteLine("Done!");
}
MyDBContext.cs looks like this:
public class MyDBContext : DbContext
{
public MyDBContext() : this("MyDb")
{
}
public MyDBContext(string connectionName) : base(connectionName) { }
public DbSet<MemberMaster> MemberMaster { get; set; }
}
I've tried to add a modelBuilder to remove Pluralizing names but that simply results in an error about the DB Context having changed....use code first...etc..etc...
Is there a better way to do this? The WebJob is being deployed via AZure with a .ZIP file and resides in the same AppService as my Website.

I turn off plurallizing on Sets and Tables by overriding the OnModelCreating, to keep both named the same, and have had no problem:
public class MyDBContext : DbContext
{
static MyDBContext()
{
Database.SetInitializer<DbContext>(null);
}
public MyDBContext() : this("MyDb")
{
}
public MyDBContext(string connectionName) : base(connectionName) { }
public DbSet<MemberMaster> MemberMaster { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Conventions.Remove<PluralizingEntitySetNameConvention>();
modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
base.OnModelCreating(modelBuilder);
}
}

Related

No parameterless constructor defined for this object with Dependency Resolver

I'm currently following "Dependancy Injection on asp net mvc 5 tutorial" in youtube. https://www.youtube.com/watch?v=27DQn6kZDFM
I follow as he said but I'm having this error.
No parameterless constructor defined for this object.
My Controller is UnityDemoController
public class UnityDemoController : Controller
{
private readonly ILocalWeaherServiceProvider _localWeaherServiceProvider;
public UnityDemoController(ILocalWeaherServiceProvider localWeaherServiceProvider)
{
_localWeaherServiceProvider = localWeaherServiceProvider;
}
//
// GET: /UnityDemo/
public ActionResult Index()
{
string currentWeatherInMyArea = _localWeaherServiceProvider.GetLocalWeatherByZipCode("0006");
return View();
}
}
IocConfiguration.cs This Configuration is under App_Start folder
public static class IocConfiguration
{
public static void ConfigureIocUnityContaioner()
{
IUnityContainer container = new UnityContainer();
RegisterServices(container);
DependencyResolver.SetResolver(new MyUnityDependancyResolver(container));
}
private static void RegisterServices(IUnityContainer container)
{
container.RegisterType<ILocalWeaherServiceProvider, LocalWeatherServiceProvider>(); // This means when somebody call/need ILocalWeaherServiceProvider then provide new Instance of the LocalWeatherServiceProvider
}
}
MyUnityDependancyResolver.cs
public class MyUnityDependancyResolver : IDependencyResolver
{
private IUnityContainer _unityContainer;
public MyUnityDependancyResolver(IUnityContainer unityContainer)
{
_unityContainer = unityContainer;
}
public object GetService(Type serviceType)
{
try
{
return _unityContainer.Resolve(serviceType);
}
catch (Exception)
{
return null;
}
}
public IEnumerable<object> GetServices(Type serviceType)
{
try
{
return _unityContainer.ResolveAll(serviceType);
}
catch (Exception)
{
return new List<object>();
}
}
}
Interface ILocalWeaherServiceProvider
public interface ILocalWeaherServiceProvider
{
string GetLocalWeatherByZipCode(string zipcode);
}
Service Class LocalWeatherServiceProvider
public class LocalWeatherServiceProvider : ILocalWeaherServiceProvider
{
public string GetLocalWeatherByZipCode(string zipcode)
{
return "Its is snowing right now in your Area : " + zipcode;
}
}
I have added Unity.
Can anyone tell me what went wrong here?
And avoid these kinds of error what are the things that I should look into these coding level?
I found out the solution by referring to below link.
https://cuttingedge.it/blogs/steven/pivot/entry.php?id=97
Change the UnityDemoController class as below.
public class UnityDemoController : Controller
{
private readonly ILocalWeaherServiceProvider _localWeaherServiceProvider;
public UnityDemoController() : this(new LocalWeatherServiceProvider())
{
}
public UnityDemoController(ILocalWeaherServiceProvider localWeaherServiceProvider)
{
_localWeaherServiceProvider = localWeaherServiceProvider;
}
//
// GET: /UnityDemo/
public ActionResult Index()
{
string currentWeatherInMyArea = _localWeaherServiceProvider.GetLocalWeatherByZipCode("0006");
return View();
}
}

Error while creating plugin in Nop Commerce

This is my first demo project in Nopcommerce and i have tried to make my own plugin but during the time of Build some error is seen. Below are some codes.
namespace Nop.Plugin.Aowi.Testimonial.Data
{
public class TestimonialRecordObjectContext : DbContext , IDbContext
{
public TestimonialRecordObjectContext(string nameOrConnectionString) : base(nameOrConnectionString) { }
#region Implementation of IDbContext
#endregion
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Configurations.Add(new TestimonialRecordMap());
base.OnModelCreating(modelBuilder);
}
public string CreateDatabaseInstallationScript()
{
return ((IObjectContextAdapter)this).ObjectContext.CreateDatabaseScript();
}
public void Install()
{
//It's required to set initializer to null (for SQL Server Compact).
//otherwise, you'll get something like "The model backing the 'your context name' context has changed since the database was created. Consider using Code First Migrations to update the database"
Database.SetInitializer<TestimonialRecordObjectContext>(null);
Database.ExecuteSqlCommand(CreateDatabaseInstallationScript());
SaveChanges();
}
public void Uninstall()
{
var dbScript = "DROP TABLE Testimonial";
Database.ExecuteSqlCommand(dbScript);
SaveChanges();
}
public new IDbSet<TEntity> Set<TEntity>() where TEntity : BaseEntity
{
return base.Set<TEntity>();
}
public System.Collections.Generic.IList<TEntity> ExecuteStoredProcedureList<TEntity>(string commandText, params object[] parameters) where TEntity : BaseEntity, new()
{
throw new System.NotImplementedException();
}
public System.Collections.Generic.IEnumerable<TElement> SqlQuery<TElement>(string sql, params object[] parameters)
{
throw new System.NotImplementedException();
}
public int ExecuteSqlCommand(string sql, bool doNotEnsureTransaction = false, int? timeout = null, params object[] parameters)
{
throw new System.NotImplementedException();
}
}
}
This is the Dependency registrar part
namespace Nop.Plugin.Aowi.Testimonial.Infastructure
{
public class DependencyRegistrar: IDependencyRegistrar
{
private const string CONTEXT_NAME ="nop_object_context_product_view_tracker";
public virtual void Register(ContainerBuilder builder, ITypeFinder typeFinder, NopConfig config)
{
//data context
this.RegisterPluginDataContext<TestimonialRecordObjectContext>(builder, CONTEXT_NAME);
//override required repository with our custom context
builder.RegisterType<EfRepository<TestimonialRecord>>()
.As<IRepository<TestimonialRecord>>()
.WithParameter(ResolvedParameter.ForNamed<IDbContext>(CONTEXT_NAME))
.InstancePerLifetimeScope();
}
public int Order
{
get { return 1; }
}
}
}
Even after cleaning and Building i am getting this error.
Can anyone help me with this. I have done all of this by watching a tutorial so if anyone can help me correct my mistake i will be really greatful.
You just need to implement this method and properties of IDbContext interface, which are described in error log, in your custom context.
for example, how it is done in one of the existing plugin Tax.CountryStateZip:
public void Detach(object entity)
{
if (entity == null)
throw new ArgumentNullException("entity");
((IObjectContextAdapter)this).ObjectContext.Detach(entity);
}
public virtual bool ProxyCreationEnabled
{
get { return this.Configuration.ProxyCreationEnabled; }
set { this.Configuration.ProxyCreationEnabled = value; }
}
public virtual bool AutoDetectChangesEnabled
{
get { return this.Configuration.AutoDetectChangesEnabled; }
set { this.Configuration.AutoDetectChangesEnabled = value; }
}
I cannot get an idea from your code that where is actual issue. But i suggest by an example.
make your install method code like:
public void Install()
{
//create the table
var dbScript = CreateDatabaseScript();
Database.ExecuteSqlCommand(dbScript);
SaveChanges();
}
Add a new class called EfStartUpTask and paste following code:
public class EfStartUpTask : IStartupTask
{
public void Execute()
{
//It's required to set initializer to null (for SQL Server Compact).
//otherwise, you'll get something like "The model backing the 'your context name' context has changed since the database was created. Consider using Code First Migrations to update the database"
Database.SetInitializer<YourContext>(null);
}
public int Order
{
//ensure that this task is run first
get { return 0; }
}
}
And your DependencyRegistrar :
public class DependencyRegistrar : IDependencyRegistrar
{
public virtual void Register(ContainerBuilder builder, ITypeFinder typeFinder)
{
builder.RegisterType<YourService>().As<YourserviceInterface>().InstancePerLifetimeScope();
//data context
this.RegisterPluginDataContext<YourContext>(builder, "nop_object_context_product_view_tracker");
//override required repository with our custom context
builder.RegisterType<EfRepository<YourEntityClass>>()
.As<IRepository<YourEntityClass>>()
.WithParameter(ResolvedParameter.ForNamed<IDbContext>("nop_object_context_product_view_tracker"))
.InstancePerLifetimeScope();
}
public int Order
{
get { return 1; }
}
}
Note: you have to change YourContext to your context name and same as for entity class
Hope this helps!

Issue in Connecting Web App with localdb using DataContext file and webConfig file

I have created MVC web application using Repository & DI approach. I have used Code First approach too.
Here is my DataContext file:
namespace EfRepPatTest.Data
{
public class DataContext : DbContext, IDbContext
{
public new IDbSet<TEntity> Set<TEntity>() where TEntity: class
{
return base.Set<TEntity>();
}
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
var typesToRegister = Assembly.GetExecutingAssembly().GetTypes()
.Where(type => !String.IsNullOrEmpty(type.Namespace))
.Where(type => type.BaseType != null && type.BaseType.IsGenericType &&
type.BaseType.GetGenericTypeDefinition() == typeof(EntityTypeConfiguration<>));
foreach (var type in typesToRegister)
{
dynamic configurationInstance = Activator.CreateInstance(type);
modelBuilder.Configurations.Add(configurationInstance);
}
base.OnModelCreating(modelBuilder);
}
}
}
I have defined connecting string in Web.Config file like below:
<add name="DataContext"
connectionString="Data Source=(LocalDB)\v11.0;AttachDbFilename=|DataDirectory|\eCommerce.mdf;Integrated Security=True"
providerName="System.Data.SqlClient"
/>
Please note here I have mentioned same name to the Connection string and my context file.
Here is my post method:
[HttpPost]
public ActionResult Create(CategoryModel model)//FormCollection collection
{
try
{
// TODO: Add insert logic here
if (model == null)
return View(model);
var category = new Category();
category.Name = model.Name;
categoryService.Insert(category);
return RedirectToAction("Index");
}
catch
{
return View(model);
}
}
CategoryService:
public class CategoryService : ICategoryService
{
private IRepository<Category> _categoryRepository;
public CategoryService(IRepository<Category> categoryRepository)
{
this._categoryRepository = categoryRepository;
}
public void Insert(Category category)
{
if (category == null)
throw new ArgumentNullException("Category");
_categoryRepository.Insert(category);
}
}
RepositoryService:
public class RepositoryService<TEntity> : IRepository<TEntity> where TEntity: class
{
private IDbContext _context;
private IDbSet<TEntity> Entities
{
get { return this._context.Set<TEntity>(); }
}
public RepositoryService(IDbContext context)
{
this._context = context;
}
public void Insert(TEntity entity)
{
Entities.Add(entity);
}
}
When I run application on the first time it will create local db. But when I going to insert data, I did not get any error from the application and it does not insert my data to the DB.
What cause this? What I have done wrong here?
Any help is appreciated!
You should call SaveChanges() on _context after all changes like this for ex.:
public void Insert(TEntity entity)
{
Entities.Add(entity);
_context.SaveChanges();
}

conditional DI with the help of config file

How can we achieve conditional Dependency Injection with the help of Unity Application block config file ? Below is my piece of code.
namespace DependencyInjection
{
//UI
class Program
{
static void Main(string[] args)
{
IUnityContainer objContainer = new UnityContainer();
objContainer.LoadConfiguration(); //loads from app
Customer obj = objContainer.Resolve<Customer>();
obj.CustomerName = "test1";
obj.Add();
}
}
//ML
public class Customer
{
private IDAL Odal;
public string CustomerName { get; set; }
public Customer(IDAL iobj)
{
Odal = iobj;
}
public void Add()
{
Odal.Add();
}
}
//DAL
public interface IDAL
{
void Add();
}
public class SQLServerDAL:IDAL
{
public void Add()
{
Console.WriteLine("SQL Server inserted");
Console.ReadLine();
}
}
public class OracleDAL:IDAL
{
public void Add()
{
Console.WriteLine("Oracle inserted");
Console.ReadLine();
}
}
}
And my config file is like below:
<unity xmlns="http://schemas.microsoft.com/practices/2010/unity">
<container>
<register type="DependencyInjection.IDAL, DependencyInjection"
mapTo="DependencyInjection.SQLServerDAL,DependencyInjection"/>
</container>
</unity>
How can I achieve the following :
If(somecondition=true)
Customer object should resolve to SQLServerDal
Else
Customer object should resolve to OracleDal
Is it possible ? If yes, how ?

Entity Framework, Unity, and MVC

I have a multi tier application using Entity Framework, MVC and Unity.
The basic setup is like this:
EF Data Access Layer
public class MyDataProvider : DbContext, IMyDataProvider
{
public MyDataProvider(SqlConnection existingConnection, bool contextOwnsConnection)
: base(existingConnection,contextOwnsConnection)
{
((IObjectContextAdapter)this).ObjectContext.CommandTimeout = 60;
Configuration.LazyLoadingEnabled = true;
Configuration.ValidateOnSaveEnabled = true;
Configuration.ProxyCreationEnabled = true;
Configuration.AutoDetectChangesEnabled = true;
}
public new IDbSet<TModel> Set<TModel>() where TModel : class
{
return base.Set<TModel>();
}
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Configurations.Add(new EmployeeMapping());
base.OnModelCreating(modelBuilder);
}
public abstract class ServiceBase<TModel> : IDisposable, IService<TModel> where TModel : class, IModel
{
[Dependency]
public IMyDataProvider MyDataProvider { get; set; }
...
}
All services inherit from this class
I then inject specific services into the Business Logic Layer like so:
public class GetEmployees
{
[Dependency("EmployeeService")]
public IEmployeeService EmployeeService { get; set;
public IQueryable<Employee> GetAllEmployees()
{
return EmployeeService.GetTable();
}
...
}
In MVC I use a controller factory
public class MyControllerFactory : DefaultControllerFactory
{
private IUnityContainer _container;
public MyControllerFactory(IUnityContainer container)
{
_container = container;
}
protected override IController GetControllerInstance(RequestContext requestContext, Type controllerType)
{
if (controllerType != null)
{
return _container.Resolve(controllerType) as IController;
}
else
{
return base.GetControllerInstance(requestContext, controllerType);
}
}
Global.asax
private static IUnityContainer InitContainer()
{
IUnityContainer unityContainer = new UnityContainer();
Bootstrapper bootstrapper = new Bootstrapper(unityContainer);
return unityContainer;
}
I pass the instance of UnityContainer into the Bootstrapper class. The Bootstrapper class self registers all assemblies.
In the MVC Controllers, I inject the Business Logic like so:
public class EmployeeController
{
[Dependency("GetEmployees")]
public IBusinessLogic GetEmployees_Operations { get; set; }
public ActionResult EmployeeMain()
{
var employees = GetEmployees_Operations.GetAllEmployees();
...
}
}
This all works great up to a point. Every so often I will get an exception thrown from MyDataProvider class: "EntityConnection can only be constructed with a closed DbConnection". This seems to happen during high use of the MVC site. The exception is simple enough to understand, but how should I go about fixing it?
I found that changing how I instantiate the business logic class from a field on the controller to inside the ActionResult method, I don't recieve the exception.
For example:
public class EmployeeController
{
//[Dependency("GetEmployees")]
//public IBusinessLogic GetEmployees_Operations { get; set; }
public ActionResult EmployeeMain()
{
IBusinessLogic GetEmployees_Operations = _ioc_Bootstrapper.Resolve(typeof(IBusinessLogic), "GetEmployees") as IBusinessLogic;
var employees = GetEmployees_Operations.GetAllEmployees();
...
}
}
Have I completely missed the boat on this and implemented Unity incorrectly?
Bootstrapper code
private void RegisterDAL(String assembly)
{
var currentAssembly = Assembly.LoadFrom(assembly);
var assemblyTypes = currentAssembly.GetTypes();
foreach (var assemblyType in assemblyTypes)
{
...
if (assemblyType.FullName.EndsWith("Provider"))
{
foreach (var requiredInterface in assemblyType.GetInterfaces())
{
if (requiredInterface.FullName.EndsWith("DataProvider"))
{
var typeFrom = assemblyType.GetInterface(requiredInterface.Name);
var typeTo = assemblyType;
var injector = GetInjectorConstructor(assemblyType.Module.Name);
RegisterType(typeFrom, typeTo, false, injector);
}
}
continue;
}
...
}
private InjectionConstructor GetInjectorConstructor(String moduleName)
{
...
connString = String.Concat("Data Source=MySqlServer, ";Initial Catalog=", catalogName, ";Application Name=", applicationName, ";Integrated Security=True; );
var conn = new SqlConnection(connString);
return new InjectionConstructor(conn, true);
}

Resources