Hello,
I'm wondering, if it's possible in the first place, how I would go about querying the database (using EF) using an ID and a table name.
For example:
QueryDynamicData(string tableName, long entityID){
return GetItem(tableName, entityID);
}
And could be called like:
var entry = QueryDynamicData("Person", 143);
Thanks in advance!
18 Answer(s)
-
0
Hi @JCompagnon,
ABP does not offer anything for this but EF might support it, have you checked it on the web ?
Thanks.
-
0
I have done some googling, but nothing useful so far has come up. I've posted a question on Stack Overflow, we'll see if anything comes of it.
Thanks for your input!
-
0
I posted the question on Stack Overflow and got some good answers. <a class="postlink" href="https://stackoverflow.com/questions/46285519/query-an-entity-framework-entity-without-knowing-the-object-type-class-table-i">https://stackoverflow.com/questions/462 ... ss-table-i</a>
I'm wondering now where would I put such a function?
I've tried adding it to the ProjectRepositoryBase.cs where it says to add common methods:
public abstract class FirstASPNetZeroRepositoryBase<TEntity, TPrimaryKey> : EfRepositoryBase<FirstASPNetZeroDbContext, TEntity, TPrimaryKey> where TEntity : class, IEntity<TPrimaryKey> { protected FirstASPNetZeroRepositoryBase(IDbContextProvider<FirstASPNetZeroDbContext> dbContextProvider) : base(dbContextProvider) { } //add your common methods for all repositories public object[] QueryDynamicData(string table, int entityID) { try { }catch(Exception e) { } return null; } }
However, when I go to an AppService class, I cannot access that method from the repository (_patientRepository will not find method QueryDyanmicData() from above)
public class PatientAppService : FirstASPNetZeroAppServiceBase, IPatientAppService { private readonly IRepository<PatientItem> _patientRepository; public PatientAppService(IRepository<PatientItem> patientRepository) { _patientRepository = patientRepository; } public async Task<PagedResultDto<PatientListDto>> GetPatientsForGrid(GetPatientsInput input) { _patientRepository //...other code
Thanks!
-
0
An update:
For now I've put the function in the AppServiceBase class in the application layer. I'm sure I'm breaking a whole lot of Best Practices, but as a rough draft / proof of concept:
public abstract class FirstASPNetZeroAppServiceBase : ApplicationService { private static readonly FirstASPNetZeroDbContext _dbContext = new FirstASPNetZeroDbContext(); private static readonly object _dbContextLock = new object(); protected FirstASPNetZeroDbContext DBContext { get { lock (_dbContextLock) { return _dbContext; } } }
protected virtual List<Dictionary<string, object>> QueryDynamicData(string table, int entityID) { try { //Get the table desired based on the table name passed PropertyInfo dbSetInfo = DBContext.GetType().GetProperties().FirstOrDefault(p => p.Name.ToLower().Equals(table.ToLower())); //Return all results from the table into IQueryable set where Id = entityID passed IQueryable anyDbSet = ((IQueryable)dbSetInfo.GetValue(DBContext)).Where("Id=" + entityID); List<Dictionary<string,object>> listObjects = new List<Dictionary<String, Object>>(); //Iterate through results foreach (Object entity in anyDbSet) { //Create dictionary of Field Name, Field Value from results Dictionary<string, object> listDBValues = entity.GetType().GetProperties().ToDictionary(propertyInfo => propertyInfo.Name, propertyInfo => propertyInfo.GetValue(entity)); //Add dictionary to list of dictionaries - useful for returning list of found results instead of just one listObjects.Add(listDBValues); } //Return list of dictionaries return listObjects; } catch (Exception e) { } return null; }protected virtual List<Dictionary<string, object>> QueryDynamicData(string table, int entityID) { try { //Get the table desired based on the table name passed PropertyInfo dbSetInfo = DBContext.GetType().GetProperties().FirstOrDefault(p => p.Name.ToLower().Equals(table.ToLower())); //Return all results from the table into IQueryable set where Id = entityID passed IQueryable anyDbSet = ((IQueryable)dbSetInfo.GetValue(DBContext)).Where("Id=" + entityID); List<Dictionary<string,object>> listObjects = new List<Dictionary<String, Object>>(); //Iterate through results foreach (Object entity in anyDbSet) { //Create dictionary of Field Name, Field Value from results Dictionary<string, object> listDBValues = entity.GetType().GetProperties().ToDictionary(propertyInfo => propertyInfo.Name, propertyInfo => propertyInfo.GetValue(entity)); //Add dictionary to list of dictionaries - useful for returning list of found results instead of just one listObjects.Add(listDBValues); } //Return list of dictionaries return listObjects; } catch (Exception e) { } return null; }
-
0
Hi,
I have the same problem. Earlier I was using ASP.Net MVC 5.x with JQuery. In this version I had made the <ProjectName>RepositoryBase class to public from protected and also its constructor to public from protected. After this I inject this in my Service constructor and I was getting the repository successfully. Once I had the repository, I was successfully calling the common methods written in <ProjectName>RepositoryBase class. Now I am using .Net Core With MVC and JQuery. I tried doing same thing here, i.e making the <ProjectName>RepositoryBase class to public from protected and also its constructor to public from protected. But when I inject this in my service constructor, I do not get the value. Instead I get the error saying service depends on <ProjectName>RepositoryBase which is not registered.
Any help on this would be appreciated.
Regards, Mahendra
-
0
Just to add to my above post, here is the exact error that I get.
An unhandled exception occurred while processing the request.
HandlerException: Can't create component 'CitiXsys.iVend365.Surcharges.SurchargeAppService' as it has dependencies to be satisfied.
'CitiXsys.iVend365.Surcharges.SurchargeAppService' is waiting for the following dependencies:
- Service 'CitiXsys.iVend365.EntityFrameworkCore.Repositories.iVend365RepositoryBase`2[[CitiXsys.iVend365.Surcharges.Surcharge, CitiXsys.iVend365.Core, Version=4.1.0.0, Culture=neutral, PublicKeyToken=null],[System.Int64, System.Private.CoreLib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]]' which was not registered. Castle.MicroKernel.Handlers.DefaultHandler.AssertNotWaitingForDependency()
-
0
Does reverting it to public work?
-
0
No. In ASP.Net version it worked, But in .Net Core version it did not work.
-
0
When I added AutoRepositoryTypes, and run the application I an not even getting the login screen. Instead I an getting the following error.
An error occurred while starting the application.
MissingMethodException: Constructor on type 'CitiXsys.iVend365.EntityFrameworkCore.Repositories.iVend365RepositoryBase`1[[Abp.Localization.ApplicationLanguage, Abp.Zero.Common, Version=3.0.0.0, Culture=neutral, PublicKeyToken=null]]' not found. System.RuntimeType.CreateInstanceImpl(BindingFlags bindingAttr, Binder binder, Object[] args, CultureInfo culture, Object[] activationAttributes, ref StackCrawlMark stackMark)
ArgumentException: Type CitiXsys.iVend365.EntityFrameworkCore.Repositories.iVend365RepositoryBase`1[[Abp.Localization.ApplicationLanguage, Abp.Zero.Common, Version=3.0.0.0, Culture=neutral, PublicKeyToken=null]] does not have a public default constructor and could not be instantiated. Castle.Core.Internal.ReflectionUtil.Instantiate<TBase>(Type subtypeofTBase, Object[] ctorArgs)
ComponentActivatorException: ComponentActivator: could not instantiate CitiXsys.iVend365.EntityFrameworkCore.Repositories.iVend365RepositoryBase`1[[Abp.Localization.ApplicationLanguage, Abp.Zero.Common, Version=3.0.0.0, Culture=neutral, PublicKeyToken=null]] Castle.MicroKernel.ComponentActivator.DefaultComponentActivator.CreateInstanceCore(ConstructorCandidate constructor, Object[] arguments, Type implType)
MissingMethodException: Constructor on type 'CitiXsys.iVend365.EntityFrameworkCore.Repositories.iVend365RepositoryBase`1[[Abp.Localization.ApplicationLanguage, Abp.Zero.Common, Version=3.0.0.0, Culture=neutral, PublicKeyToken=null]]' not found. System.RuntimeType.CreateInstanceImpl(BindingFlags bindingAttr, Binder binder, Object[] args, CultureInfo culture, Object[] activationAttributes, ref StackCrawlMark stackMark) System.Activator.CreateInstance(Type type, BindingFlags bindingAttr, Binder binder, Object[] args, CultureInfo culture, Object[] activationAttributes) System.Activator.CreateInstance(Type type, Object[] args) Castle.Core.Internal.ReflectionUtil.Instantiate<TBase>(Type subtypeofTBase, Object[] ctorArgs)
Show raw exception details ArgumentException: Type CitiXsys.iVend365.EntityFrameworkCore.Repositories.iVend365RepositoryBase`1[[Abp.Localization.ApplicationLanguage, Abp.Zero.Common, Version=3.0.0.0, Culture=neutral, PublicKeyToken=null]] does not have a public default constructor and could not be instantiated. Castle.Core.Internal.ReflectionUtil.Instantiate
Show raw exception details ComponentActivatorException: ComponentActivator: could not instantiate CitiXsys.iVend365.EntityFrameworkCore.Repositories.iVend365RepositoryBase`1[[Abp.Localization.ApplicationLanguage, Abp.Zero.Common, Version=3.0.0.0, Culture=neutral, PublicKeyToken=null]] Castle.MicroKernel.ComponentActivator.DefaultComponentActivator.CreateInstanceCore(ConstructorCandidate constructor, Object[] arguments, Type implType) Castle.MicroKernel.ComponentActivator.DefaultComponentActivator.CreateInstance(CreationContext context, ConstructorCandidate constructor, Object[] arguments) Castle.MicroKernel.ComponentActivator.DefaultComponentActivator.InternalCreate(CreationContext context) Castle.MicroKernel.ComponentActivator.AbstractComponentActivator.Create(CreationContext context, Burden burden) Castle.MicroKernel.Lifestyle.AbstractLifestyleManager.CreateInstance(CreationContext context, bool trackedExternally) Castle.MicroKernel.Lifestyle.AbstractLifestyleManager.Resolve(CreationContext context, IReleasePolicy releasePolicy) Castle.MicroKernel.Handlers.DefaultHandler.ResolveCore(CreationContext context, bool requiresDecommission, bool instanceRequired, out Burden burden) Castle.MicroKernel.Handlers.DefaultHandler.Resolve(CreationContext context, bool instanceRequired) Castle.MicroKernel.Resolvers.DefaultDependencyResolver.Resolve(CreationContext context, ISubDependencyResolver contextHandlerResolver, ComponentModel model, DependencyModel dependency) Castle.MicroKernel.ComponentActivator.DefaultComponentActivator.CreateConstructorArguments(ConstructorCandidate constructor, CreationContext context) Castle.MicroKernel.ComponentActivator.DefaultComponentActivator.Instantiate(CreationContext context) Castle.MicroKernel.ComponentActivator.DefaultComponentActivator.InternalCreate(CreationContext context) Castle.MicroKernel.ComponentActivator.AbstractComponentActivator.Create(CreationContext context, Burden burden) Castle.MicroKernel.Lifestyle.AbstractLifestyleManager.CreateInstance(CreationContext context, bool trackedExternally) Castle.MicroKernel.Lifestyle.SingletonLifestyleManager.Resolve(CreationContext context, IReleasePolicy releasePolicy) Castle.MicroKernel.Handlers.DefaultHandler.ResolveCore(CreationContext context, bool requiresDecommission, bool instanceRequired, out Burden burden) Castle.MicroKernel.Handlers.DefaultHandler.Resolve(CreationContext context, bool instanceRequired) Castle.MicroKernel.Resolvers.DefaultDependencyResolver.Resolve(CreationContext context, ISubDependencyResolver contextHandlerResolver, ComponentModel model, DependencyModel dependency) Castle.MicroKernel.ComponentActivator.DefaultComponentActivator.CreateConstructorArguments(ConstructorCandidate constructor, CreationContext context) Castle.MicroKernel.ComponentActivator.DefaultComponentActivator.Instantiate(CreationContext context) Castle.MicroKernel.ComponentActivator.DefaultComponentActivator.InternalCreate(CreationContext context) Castle.MicroKernel.ComponentActivator.AbstractComponentActivator.Create(CreationContext context, Burden burden) Castle.MicroKernel.Lifestyle.AbstractLifestyleManager.CreateInstance(CreationContext context, bool trackedExternally) Castle.MicroKernel.Lifestyle.AbstractLifestyleManager.Resolve(CreationContext context, IReleasePolicy releasePolicy) Castle.MicroKernel.Handlers.DefaultHandler.ResolveCore(CreationContext context, bool requiresDecommission, bool instanceRequired, out Burden burden) Castle.MicroKernel.Handlers.DefaultHandler.Resolve(CreationContext context, bool instanceRequired) Castle.MicroKernel.Resolvers.DefaultDependencyResolver.Resolve(CreationContext context, ISubDependencyResolver contextHandlerResolver, ComponentModel model, DependencyModel dependency) Castle.MicroKernel.ComponentActivator.DefaultComponentActivator.CreateConstructorArguments(ConstructorCandidate constructor, CreationContext context) Castle.MicroKernel.ComponentActivator.DefaultComponentActivator.Instantiate(CreationContext context) Castle.MicroKernel.ComponentActivator.DefaultComponentActivator.InternalCreate(CreationContext context) Castle.MicroKernel.ComponentActivator.AbstractComponentActivator.Create(CreationContext context, Burden burden) Castle.MicroKernel.Lifestyle.AbstractLifestyleManager.CreateInstance(CreationContext context, bool trackedExternally) Castle.MicroKernel.Lifestyle.AbstractLifestyleManager.Resolve(CreationContext context, IReleasePolicy releasePolicy) Castle.MicroKernel.Handlers.DefaultHandler.ResolveCore(CreationContext context, bool requiresDecommission, bool instanceRequired, out Burden burden) Castle.MicroKernel.Handlers.DefaultHandler.Resolve(CreationContext context, bool instanceRequired) Castle.MicroKernel.Resolvers.DefaultDependencyResolver.Resolve(CreationContext context, ISubDependencyResolver contextHandlerResolver, ComponentModel model, DependencyModel dependency) Castle.MicroKernel.ComponentActivator.DefaultComponentActivator.CreateConstructorArguments(ConstructorCandidate constructor, CreationContext context) Castle.MicroKernel.ComponentActivator.DefaultComponentActivator.Instantiate(CreationContext context) Castle.MicroKernel.ComponentActivator.DefaultComponentActivator.InternalCreate(CreationContext context) Castle.MicroKernel.ComponentActivator.AbstractComponentActivator.Create(CreationContext context, Burden burden) Castle.MicroKernel.Lifestyle.AbstractLifestyleManager.CreateInstance(CreationContext context, bool trackedExternally) Castle.MicroKernel.Lifestyle.SingletonLifestyleManager.Resolve(CreationContext context, IReleasePolicy releasePolicy) Castle.MicroKernel.Handlers.DefaultHandler.ResolveCore(CreationContext context, bool requiresDecommission, bool instanceRequired, out Burden burden) Castle.MicroKernel.Handlers.DefaultHandler.Resolve(CreationContext context, bool instanceRequired) Castle.MicroKernel.DefaultKernel.ResolveComponent(IHandler handler, Type service, IDictionary additionalArguments, IReleasePolicy policy) Castle.MicroKernel.DefaultKernel.Castle.MicroKernel.IKernelInternal.Resolve(Type service, IDictionary arguments, IReleasePolicy policy) Castle.Windsor.WindsorContainer.Resolve<T>() Abp.AbpKernelModule.PostInitialize() in AbpKernelModule.cs System.Collections.Generic.List.ForEach(Action<T> action) Abp.AbpBootstrapper.Initialize() in AbpBootstrapper.cs Abp.AspNetCore.AbpApplicationBuilderExtensions.UseAbp(IApplicationBuilder app, Action<AbpApplicationBuilderOptions> optionsAction) in AbpApplicationBuilderExtensions.cs CitiXsys.iVend365.Web.Startup.Startup.Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory) in Startup.cs + app.UseAbp(options => System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() Microsoft.AspNetCore.Hosting.ConventionBasedStartup.Configure(IApplicationBuilder app) Microsoft.AspNetCore.ApplicationInsights.HostingStartup.ApplicationInsightsLoggerStartupFilter+<>c__DisplayClass0_1.<Configure>b__0(IApplicationBuilder builder) Microsoft.ApplicationInsights.AspNetCore.ApplicationInsightsStartupFilter+<>c__DisplayClass0_0.<Configure>b__0(IApplicationBuilder app) Microsoft.AspNetCore.Server.IISIntegration.IISSetupFilter+<>c__DisplayClass3_0.<Configure>b__0(IApplicationBuilder app) Microsoft.AspNetCore.Hosting.Internal.AutoRequestServicesStartupFilter+<>c__DisplayClass0_0.<Configure>b__0(IApplicationBuilder builder) Microsoft.AspNetCore.Hosting.Internal.WebHost.BuildApplication()
Show raw exception details .NET Core 4.6.00001.0 X64 v4.0.0.0 | Microsoft.AspNetCore.Hosting version 2.0.0-rtm-26452 | Microsoft Windows 10.0.15063 | Need help?
-
0
It says right there:
ArgumentException: Type CitiXsys.iVend365.EntityFrameworkCore.Repositories.iVend365RepositoryBase`1[[Abp.Localization.ApplicationLanguage, Abp.Zero.Common, Version=3.0.0.0, Culture=neutral, PublicKeyToken=null]] does not have a public default constructor and could not be instantiated.
You need to provide a public default constructor.
-
0
Not sure why its saying that.....I trust ABP already provides the default public constructor... See below code..
public class iVend365RepositoryBase<TEntity, TPrimaryKey> : EfCoreRepositoryBase<iVend365DbContext, TEntity, TPrimaryKey> where TEntity : class, IEntity<TPrimaryKey> {
public iVend365RepositoryBase(IDbContextProvider<iVend365DbContext> dbContextProvider) : base(dbContextProvider) { }
...... ...... ......
-
0
Check that you have the following in your module:
public override void Initialize() { IocManager.RegisterAssemblyByConvention(Assembly.GetExecutingAssembly()); }
-
0
yes, it's there....see below...
public override void Initialize() { IocManager.RegisterAssemblyByConvention(typeof(iVend365EntityFrameworkCoreModule).GetAssembly()); }
-
0
How are you injecting iVend365RepositoryBase?
-
0
Like below...
public class SurchargeAppService : iVend365AppServiceBase, ISurchargeAppService { private readonly IRepository<Surcharge, long> _SurchargeRepository; private readonly iVend365RepositoryBase<Surcharge, long> _iVendRepository; private readonly IRepository<TaxCode, long> _TaxCodeRepository; private readonly IBackgroundJobManager _backgroundJobManager;
public SurchargeAppService(iVend365RepositoryBase<Surcharge, long> iVendRepository, IRepository<Surcharge, long> SurchargeRepository, IRepository<TaxCode, long> TaxCodeRepository, IBackgroundJobManager backgroundJobManager) { _iVendRepository = iVendRepository; _SurchargeRepository = SurchargeRepository; _TaxCodeRepository = TaxCodeRepository; _backgroundJobManager = backgroundJobManager; }
-
0
Ah, since you're not using an interface, it won't be registered by convention. You should do self-registration.
IocManager.Register<iVend365RepositoryBase>(DependencyLifeStyle.Transient);
-
0
Thanks aaron.....Much appreciated....the problem is sorted out by registering....