Autofac and Background processes - c#

I am using WebApi 2 and have the need to fire off a process in the background. I need it to do it's stuff and not affect the current request.
So after some digging around I found that I could just use
public void Save(Order model) => Task.Run(() => postmanService.Update(model));
I wanted to debug it to make sure it was working, so I change it to this:
public void Save(Order model) => await postmanService.Update(model).ConfigureAwait(false);
But when I run this I get this error:
"The ObjectContext instance has been disposed and can no longer be used for operations that require a connection."
I am not sure why this is happening because my DatabaseContext is registered like this:
builder.RegisterType<DatabaseContext>().As<DbContext>().InstancePerLifetimeScope();
builder.RegisterType<UnitOfWork>().As<IUnitOfWork>().InstancePerLifetimeScope();
builder.RegisterType<CollectionManagerProvider>().As<ICollectionManagerProvider>().InstancePerRequest();
builder.RegisterType<PostmanService>().As<IPostmanService>();
The PostmanService is what saves the data to the database and it looks like this:
public class PostmanService : Service<Postman>, IPostmanService
{
public PostmanService(IUnitOfWork unitOfWork) : base(unitOfWork)
{}
/// <summary>
/// Save or update a message
/// </summary>
/// <param name="model"></param>
public void Save(Postman model)
{
if (model.Id == 0)
Repository.Create(model);
else
Repository.Update(model);
}
/////////--------- Removed for brevity ---------/////////
}
The repository looks like this:
public class Repository<T> : IRepository<T> where T : class
{
// Create our private properties
private readonly DbContext _context;
private readonly DbSet<T> _dbEntitySet;
/// <summary>
/// Default constructor
/// </summary>
/// <param name="context">The database context</param>
public Repository(DbContext context)
{
// Assign our context and entity set
_context = context ?? throw new ArgumentNullException("context");
_dbEntitySet = context.Set<T>();
}
/// <summary>
/// Creates an entity
/// </summary>
/// <param name="model"></param>
public void Create(T model) => _dbEntitySet.Add(model);
/// <summary>
/// Updates an entity
/// </summary>
/// <param name="model"></param>
public void Update(T model) => _context.Entry<T>(model).State = EntityState.Modified;
/////////--------- Removed for brevity ---------/////////
}
And finally, the unit of work looks like this:
public class UnitOfWork : IUnitOfWork
{
private readonly Dictionary<Type, object> _repositories;
// Public properties
public DbContext Context { get; }
/// <summary>
/// Default constructor
/// </summary>
public UnitOfWork(DbContext context)
{
Context = context;
_repositories = new Dictionary<Type, object>();
}
/// <summary>
/// Gets the entity repository
/// </summary>
/// <typeparam name="TEntity">The entity model</typeparam>
/// <returns></returns>
public IRepository<TEntity> GetRepository<TEntity>() where TEntity : class
{
// If our repositories have a matching repository, return it
if (_repositories.Keys.Contains(typeof(TEntity)))
return _repositories[typeof(TEntity)] as IRepository<TEntity>;
// Create a new repository for our entity
var repository = new Repository<TEntity>(Context);
// Add to our list of repositories
_repositories.Add(typeof(TEntity), repository);
// Return our repository
return repository;
}
/// <summary>
/// Saves the database changes asynchronously
/// </summary>
/// <returns></returns>
public async Task SaveChangesAsync()
{
try
{
// Save the changes to the database
await Context.SaveChangesAsync();
}
catch (DbEntityValidationException ex) {
// Retrieve the error messages as a list of strings.
var errorMessages = ex.EntityValidationErrors.SelectMany(x => x.ValidationErrors).Select(x => x.ErrorMessage);
// Join the list to a single string.
var fullErrorMessage = string.Join("; ", errorMessages);
// Combine the original exception message with the new one.
var exceptionMessage = string.Concat(ex.Message, " The validation errors are: ", fullErrorMessage);
// Throw a new DbEntityValidationException with the improved exception message.
throw new DbEntityValidationException(exceptionMessage, ex.EntityValidationErrors);
}
}
}
I am not sure if the issue is with the CollectionManagerProvider and how that is registered (Because I have registered it as InstancePerRequest and techinically the method is being fired on a different thread.
Can someone help me with this?

One option would be to use Owned - http://docs.autofac.org/en/latest/advanced/owned-instances.html , and take the responsibility of disposal upon yourself.
public Repository(Owned<DbContext> context)
public PostmanService(Owned<IUnitOfWork> unitOfWork)
etc etc
or:
builder.RegisterType<DatabaseContext>().As<DbContext>().Inst‌​ancePerLifetimeScope‌​().ExternallyOwned()‌​;
builder.RegisterType<UnitOfWork>().As<IUnitOfWork>().InstancePerLifetimeScope().ExternallyOwned()‌​;
etc etc
See:
http://docs.autofac.org/en/latest/advanced/owned-instances.html
http://docs.autofac.org/en/latest/lifetime/disposal.html

Related

c# - Can I refactor functions that have similar inputs but call different services into one generic function?

I am looking for a way to combine x amount of very similar CRUD functions into one without having to use x amount of if else statements to check the type of a generic.
I have Web API controllers that I want to make calls from like this:
Service.Get<FooModel>(number, type, part, version);
This is to prevent having to have an extremely similar function for 40+ API endpoints. The issue is when I receive this in my service, I have to check the type of the generic given and compare with those 40+ object types in the one function. All of the models currently inherit from a base inherited model.
Current generic function
(Create, Update, Delete functions are similar):
public T Get<T>(string documentNr, string type, string part, string version) where T : InheritedModel, new()
{
try
{
T model = new T();
if (typeof(T) == typeof(InheritedModel))
{
using (var repo = new InheritedModelConsumer(ref _helper))
{
model = (T)repo.Get(documentNr, type, part, version);
}
}
else if (typeof(T) == typeof(FooModel))
{
using (var repo = new FooModelConsumer(ref _helper))
{
model = (T)(object)repo.Get(documentNr, type, part, version);
}
}
else if (typeof(T) == typeof(ComponentModel))
{
using (var repo = new ComponentModelConsumer(ref _helper))
{
model = (T)(object)repo.Get(documentNr, type, part, version);
}
}
else if (typeof(T) == typeof(BarModel))
{
using (var repo = new BarModelConsumer(ref _helper))
{
model = (T)(object)repo.Get(documentNr, type, part, version);
}
}
... and so on
... and so on
...
else
throw new Exception("Type T structure not defined");
return model;
}
catch (Exception)
{
throw;
}
finally
{
_helper.Dispose();
}
}
This does work, but if it is possible I am looking for something where I can say at run time, "oh I have this object of Type T, and well since I know the functions all have the same inputs I'm going to instantiate this consumer of Type TConsumer, call consumer.Get(inputs), and then return an object of T to whatever API controller called me."
Edit
Example of a simple consumer class in use
internal sealed class FooConsumer : RepositoryConsumer<Foo, FooRepository, FooFilter>
{
public FooConsumer(ref SqlHelper helper) : base(ref helper) { }
public List<Foo> GetAll(string token)
{
return _repo.Get().Where(x => Extensions.StringContainsToken(x.AccountName, token)).ToList();
}
}
Repository Consumer that all consumers inherit from .
T is the model, K is the Repository (custom ORM class), and O is Filter for the WHERE clause the ORM executes.
public abstract class RepositoryConsumer<T, K, O> : IDisposable, IRepositoryConsumer<T> where T : class, new() where K : Repository<T, O>, new() where O : QueryFilter, new()
{
/// <summary>
/// Repository instance
/// </summary>
protected K _repo;
/// <summary>
/// Only constructor avaialble. MUst pass SqlHelper instance for transaction support
/// </summary>
/// <param name="sql"></param>
public RepositoryConsumer(ref SqlHelper sql)
{
_repo = Activator.CreateInstance(typeof(K), new object[] { sql }) as K;
}
/// <summary>
/// Allow consumer initializations in using statements
/// </summary>
public void Dispose()
{
}
/// <summary>
/// Create instance of T
/// </summary>
/// <param name="data"></param>
/// <returns></returns>
public virtual int Create(T data)
{
return _repo.Create(data);
}
/// <summary>
/// Bulk create instances of T
/// </summary>
/// <param name="contract"></param>
/// <returns></returns>
public virtual int Create(BaseBulkable<T> contract)
{
return _repo.BulkCreate(contract);
}
/// <summary>
/// Get an instance of T based on a single PK field id
/// </summary>
/// <param name="id"></param>
/// <returns></returns>
public virtual T Get(long id)
{
return _repo.Get(id);
}
/// <summary>
/// Gets all instances of T
/// </summary>
/// <returns></returns>
public virtual List<T> GetAll()
{
return _repo.Get();
}
/// <summary>
/// Updates an instance of T
/// </summary>
/// <param name="data"></param>
/// <returns></returns>
public virtual int Update(T data)
{
return _repo.Update(data);
}
/// <summary>
/// Updates an instance of T based on a single PK field id
/// </summary>
/// <param name="id"></param>
/// <param name="data"></param>
/// <returns></returns>
public virtual int Update(long id, T data)
{
return _repo.Update(id, data);
}
/// <summary>
/// Deletes an instance of T
/// </summary>
/// <param name="data"></param>
/// <returns></returns>
public virtual int Delete(T data)
{
return _repo.Delete(data);
}
/// <summary>
/// Deletes an instance of T based on a single PK field id
/// </summary>
/// <param name="id"></param>
/// <returns></returns>
public virtual int Delete(long id)
{
return _repo.Delete(id);
}
}

Entity Framework : deleting child entities

I am using EF, but I have lazy loading disabled. Instead I am using eager loading, so I created my own service:
/// <summary>
/// Generic service for entity framework
/// </summary>
/// <typeparam name="T">An entity model</typeparam>
public class Service<T> : IService<T> where T : class
{
// Create our private properties
private readonly DbContext _context;
private readonly DbSet<T> _dbEntitySet;
/// <summary>
/// Default constructor
/// </summary>
/// <param name="context">The database context</param>
public Service(DbContext context)
{
// Assign our context and entity set
_context = context ?? throw new ArgumentNullException("context");
_dbEntitySet = context.Set<T>();
}
/// <summary>
/// Gets all the entities
/// </summary>
/// <param name="includes">Option includes for eager loading</param>
/// <returns></returns>
public IQueryable<T> List(params string[] includes)
{
// Create a query
IQueryable<T> query = _dbEntitySet;
// For each include, append to our query
if (includes != null)
foreach (var include in includes)
query = query.Include(include);
// Return our query
return query;
}
/// <summary>
/// Creates an entity
/// </summary>
/// <param name="model"></param>
public void Create(T model) => _dbEntitySet.Add(model);
/// <summary>
/// Updates an entity
/// </summary>
/// <param name="model"></param>
public void Update(T model) => _context.Entry<T>(model).State = EntityState.Modified;
/// <summary>
/// Removes an entity
/// </summary>
/// <param name="model"></param>
public void Remove(T model) => _context.Entry<T>(model).State = EntityState.Deleted;
/// <summary>
/// Saves the database context changes
/// </summary>
/// <returns></returns>
public async Task SaveChangesAsync()
{
try
{
// Save the changes to the database
await _context.SaveChangesAsync();
}
catch (DbEntityValidationException ex)
{
// Retrieve the error messages as a list of strings.
var errorMessages = ex.EntityValidationErrors.SelectMany(x => x.ValidationErrors).Select(x => x.ErrorMessage);
// Join the list to a single string.
var fullErrorMessage = string.Join("; ", errorMessages);
// Combine the original exception message with the new one.
var exceptionMessage = string.Concat(ex.Message, " The validation errors are: ", fullErrorMessage);
// Throw a new DbEntityValidationException with the improved exception message.
throw new DbEntityValidationException(exceptionMessage, ex.EntityValidationErrors);
}
catch (DbUpdateException ex)
{
throw;
}
}
/// <summary>
/// Executes a stored procedure in sql
/// </summary>
/// <param name="procedure">The name of the sproc</param>
/// <param name="parameters">the sql params for the sproc</param>
/// <returns></returns>
public DbRawSqlQuery<T> ExecuteProcedure(string procedure, List<SqlParameter> parameters)
{
var results = _context.Database.SqlQuery<T>($"exec {procedure} { CreateQueryStringFromParams(parameters) }");
return results;
}
/// <summary>
/// Dispose
/// </summary>
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
/// <summary>
/// Creates the input string to run sprocs in sql with EF by converting the sql params into a nice string
/// </summary>
/// <param name="parameters"></param>
/// <returns></returns>
private static string CreateQueryStringFromParams(IEnumerable<SqlParameter> parameters)
{
var response = "";
var list = parameters as IList<SqlParameter> ?? parameters.ToList();
var length = list.Count;
for (var i = 0; i < length; i++)
{
response += $"{list[i].ParameterName}=\"{list[i].Value}\"";
if (i != length - 1)
response += ", ";
}
return response;
}
/// <summary>
/// Disposes of any attached resources
/// </summary>
/// <param name="disposing">A boolean indicating whether the object is being disposed</param>
protected virtual void Dispose(bool disposing)
{
// If we are disposing, dispose of our context
if (disposing)
_context.Dispose();
}
}
Each service then inherits this class:
/// <summary>
/// Handles all Group related methods
/// </summary>
public class GroupService : Service<Group>, IGroupService
{
/// <summary>
/// The default constructor
/// </summary>
/// <param name="unitOfWork"></param>
public GroupService(DbContext context) : base(context)
{
}
/// <summary>
/// Lists groups by category
/// </summary>
/// <param name="categoryId">The id of the category</param>
/// <param name="includes"></param>
/// <returns></returns>
public IQueryable<Group> List(int categoryId, params string[] includes) => List(includes).Where(m => m.CategoryId == categoryId);
/// <summary>
/// Gets a single Group by id
/// </summary>
/// <param name="id">The id of the Group</param>
/// <returns></returns>
public async Task<Group> GetAsync(int id, params string[] includes) => await List(includes).Where(model => model.Id == id).SingleOrDefaultAsync();
}
Each "entity" has a class similar to this GroupService.
I also have providers for each entity type too and here is my delete method:
/// <summary>
/// Delete a Group
/// </summary>
/// <param name="id">The Group id</param>
/// <returns></returns>
public async Task<bool> DeleteAsync(int id)
{
// Get our model
var model = await _service.GetAsync(id, "Questions");
// For each question, remove from the database
if (model.Questions != null)
foreach (var question in model.Questions.ToList())
if (!await _questionProvider.Value.DeleteAsync(question.Id, false))
throw new Exception("Failed to delete the questions");
// Update our Questions
model.Questions = null;
// Save our model
_service.Remove(model);
// Save the database changes
await _service.SaveChangesAsync();
// Return true
return true;
}
As you can see, I just pull back the questions.
If there are some questions, then I invoke the questionProvider's delete method, which is very similar:
/// <summary>
/// Delete a question
/// </summary>
/// <param name="id">The question id</param>
/// <param name="saveChanges">Saves the changes to the database after the delete (default true)</param>
/// <returns></returns>
public async Task<bool> DeleteAsync(int id, bool saveChanges = true)
{
// Get our model
var model = await _service.GetAsync(id, "Answers");
// For each answer, delete from the database
if (model.Answers != null)
foreach (var answer in model.Answers.ToList())
if (!await _answerProvider.Value.DeleteAsync(answer.Id, false))
throw new Exception("Failed to delete the answers");
// Update our Answers
model.Answers = null;
// Save our model
_service.Remove(model);
// Save the database changes
if (saveChanges) await _service.SaveChangesAsync();
// Return true
return true;
}
As you can see, I do not save the context changes until all children have been removed. Now I must point out that I am not removing the child directly from the parent. Instead I am removing the entity from it's own collection and then setting the property to null. After it is all done I save the changes, but I am getting this error:
The operation failed: The relationship could not be changed because one or more of the foreign-key properties is non-nullable. When a change is made to a relationship, the related foreign-key property is set to a null value. If the foreign-key does not support null values, a new relationship must be defined, the foreign-key property must be assigned another non-null value, or the unrelated object must be deleted.
Does anyone know how I can delete the entities in a method similar to what I am trying to achieve?
This was rather easy to fix after reading some other people with similar issues. I just changed one line of code in my Service.cs from:
public void Remove(T model) => _context.Entry<T>(model).State = EntityState.Deleted;
to:
public void Remove(T model) => _dbEntitySet.Remove(model);
And that worked.
Update
I also found that the eager load needs to include all the navigation properties that will be affected.
So if I was to delete a Question which has Answers and Answers have Formulas, the Get invocation would have to be:
var model = await _service.GetAsync(id, "Answers.Formulas");
If you don't include that, you will get an error.

ASP.NET Identity - Custom role validation not being called

I am trying to the create a custom RoleValidator object to validate my custom IdentityRole. I have created an ApplicaitonRoleValidator class that inherits from RoleValidator and set this as the RoleValidator in my ApplicationRoleManager class. But when I create new role the validation function ValidateAsync is never called.
I have tried looking at similar questions implementing UserValidator like How can customize Asp.net Identity 2 username already taken validation message?
and this one ASP.NET Identity - setting UserValidator does nothing but cannot get it to work.
/// <summary>
/// Custom role validator, used to validate new instances of ApplicationRole that are added to the system.
/// </summary>
/// <typeparam name="TRole">The type of the role.</typeparam>
public class ApplicationRoleValidator<TRole> : RoleValidator<TRole> where TRole : ApplicationRole
{
private RoleManager<TRole, string> Manager { get; set; }
/// <summary>
/// Initializes a new instance of the <see cref="ApplicationRoleValidator" /> class.
/// </summary>
/// <param name="manager">The manager.</param>
public ApplicationRoleValidator(RoleManager<TRole, string> manager) : base(manager)
{
Manager = manager;
}
/// <summary>
/// Validates a role before saving.
/// </summary>
/// <param name="item"></param>
/// <returns></returns>
/// <exception cref="System.ArgumentNullException">item</exception>
public override async Task<IdentityResult> ValidateAsync(TRole item)
{
if (item == null)//<= break point here never reached.
{
throw new ArgumentNullException(nameof(item));
}
var rslt = base.ValidateAsync(item);
if (rslt.Result.Errors.Any())
{//return error if found
return IdentityResult.Failed(rslt.Result.Errors.ToArray());
}
var errors = new List<string>();
//validate the min num of members
if (role.MinimumNumberOfMembers < 0)
{
errors.Add(string.Format(CultureInfo.CurrentCulture, "最小数は0以上でなければなりません。"));
}
return errors.Count > 0 ? IdentityResult.Failed(errors.ToArray()) : IdentityResult.Success;
}
}
ApplicationRoleManager where the custom RoleValidator is set during create. I can break on that line so I know it is being called.
public class ApplicationRoleManager : RoleManager<ApplicationRole, string>
{
/// <summary>
/// Initializes a new instance of the <see cref="ApplicationRoleManager"/> class.
/// </summary>
/// <param name="store"></param>
public ApplicationRoleManager(IRoleStore<ApplicationRole, string> store)
: base(store)
{
}
/// <summary>
/// Creates the specified options.
/// </summary>
/// <param name="options">The options.</param>
/// <param name="context">The context.</param>
/// <returns></returns>
public static ApplicationRoleManager Create(IdentityFactoryOptions<ApplicationRoleManager> options, IOwinContext context)
{
var manager = new ApplicationRoleManager(new ApplicationRoleStore(context.Get<MyContext>()));
manager.RoleValidator = new ApplicationRoleValidator<ApplicationRole>(manager);
return manager;
}
}
public class ApplicationRole : IdentityRole<string, ApplicationUserRole>
{
public bool IsSystemGroup { get; set; }
public string Description { get; set; } = "";
public int MinimumNumberOfMembers { get; set; }
}
public class ApplicationRoleStore : RoleStore<ApplicationRole, string, ApplicationUserRole>
{
public ApplicationRoleStore(MyContext context)
: base(context)
{
}
}
The role is being created by call to Create on the ApplicationRoleManager
var store = new ApplicationRoleStore(new MyContext());
var manager = new ApplicationRoleManager(store);
manager.Create(group);
You are setting the ApplicationRoleValidator as RoleValidator of ApplicationRoleManager in Create method of ApplicationRoleManager. In the 3 last lines of code you posted, you are newing an instance of ApplicationRoleManager. This instance of ApplicationRoleManager gets the default RoleValidator.
If you want to new an instance of ApplicationRoleManager you have to put that logic inside constructor
public ApplicationRoleManager(IRoleStore<ApplicationRole, string> store) : base(store)
{
RoleValidator = new ApplicationRoleValidator<ApplicationRole>(this);
}

No parameterless constructor defined for this object MVC4

This question already asked so many time and also tried and created default contructor for my model class but still i m getting error.below are my code lines, i want to know if somebody can help me to fix my code..
public class RecordController: Controller
{
private readonly IRecord _DataService = null;
public RecordController(IRecord dataService )
{
_DataService = dataService ;
}
[HttpGet]
public ActionResult TestRecord()
{
return View();
}
[HttpPost]
public ActionResult TestRecord(TestRecordModel model)
{
return View();
}
}
Below is my TestRecordModel class
public class TestRecordModel
{
[Required]
[Display(Name = "UserNo #:)]
public string UserNo { get; set; }
}
Below is my bootstrapper,WindsorControllerActivator and ControllerInstaller
public class Bootstrapper
{
#region Properties
public static IWindsorContainer Container { get; private set; }
#endregion
/// <summary>
/// Initialises this instance.
/// </summary>
public static void RegisterAllTypes()
{
// adds and configures all components using WindsorInstallers from executing assembly.
Container = new WindsorContainer().Install(FromAssembly.InThisApplication());
Container.Register(Component.For<IViewEngine>().ImplementedBy<RazorViewEngine>());
Container.Register(Component.For<IControllerFactory>().ImplementedBy<WindsorControllerFactory>());
Container.Register(Component.For<IControllerActivator>().ImplementedBy<WindsorControllerActivator>());
Container.Register(Component.For<IHttpControllerActivator>().ImplementedBy<WindsorHttpControllerActivator>());
DependencyResolver.SetResolver(new WindsorDependencyResolver(Container.Kernel));
GlobalConfiguration.Configuration.DependencyResolver = new WindsorHttpDependencyResolver(Container.Kernel);
}
public static void RegisterType<TContract, TImplementation>(params KeyValuePair<string, string>[] parameters)
where TContract : class
where TImplementation : TContract
{
var dependencies = parameters
.Select(parameter => Parameter.ForKey(parameter.Key).Eq(parameter.Value))
.Select(dummy => (Dependency)dummy).ToArray();
Container.Register(Component.For<TContract>()
.ImplementedBy<TImplementation>()
.DependsOn(dependencies));
}
public static TContract Resolve<TContract>()
{
return Container.Resolve<TContract>();
}
/// <summary>
/// Releases unmanaged and - optionally - managed resources.
/// </summary>
public static void Dispose()
{
// clean up, application exits.
if (Container != null)
Container.Dispose();
}
}
public class WindsorControllerActivator : IControllerActivator
{
#region Private Members
private readonly IKernel _kernel;
#endregion
#region Constructor(s)
/// <summary>
/// Initializes a new instance of the <see cref="WindsorControllerActivator" /> class.
/// </summary>
/// <param name="kernel">The kernel.</param>
public WindsorControllerActivator(IKernel kernel)
{
_kernel = kernel;
}
#endregion
#region IControllerActivator Members
/// <summary>
/// When implemented in a class, creates a controller.
/// </summary>
/// <param name="requestContext">The request context.</param>
/// <param name="controllerType">The controller type.</param>
/// <returns>
/// The created controller.
/// </returns>
public IController Create(RequestContext requestContext, Type controllerType)
{
return (IController)_kernel.Resolve(controllerType);
}
#endregion
}
public class ControllerInstaller : InstallerBase
{
/// <summary>
/// Performs the installation in the <see cref="T:Castle.Windsor.IWindsorContainer" />.
/// </summary>
/// <param name="container">The container.</param>
/// <param name="store">The configuration store.</param>
/// <exception cref="System.NotImplementedException"></exception>
public override void Install(IWindsorContainer container, IConfigurationStore store)
{
container.Register(
Classes.FromAssemblyInDirectory(new AssemblyFilter(GetExecutingDirectory()))
.BasedOn<IController>()
.LifestyleTransient());
}
}
Maybe if you try use serialize or Activator.CreateInstance(t) then you will get the error about parameterless constructor.
The error you are getting is the standard error when the mvc framework creates a controller. I Think that you registration/bootstrapper is not being called correctly.
Set a breakpoint inside WindsorControllerActivator to see if it gets called.

Stored Procedure loses connection

I have an ASP.NET MVC project in which the model is managed through .NET entities and it seems that some times it loses the connection, but this happens only on stored procedures.
I get the following error:
Execution of the command requires an open and available connection. The connection's current state is broken.
Why is this happening?
Code
public ObjectResult<Categories> GetCategoriesStructure() {
return ObjectContext.getCategoriesStructure();
}
var catss = GetCategoriesStructure().ToList();
this exception occurs when I am trying to assign the List to catss variable
Object Context Instantiation
public abstract class ObjectContextManager {
/// <summary>
/// Returns a reference to an ObjectContext instance.
/// </summary>
public abstract TObjectContext GetObjectContext<TObjectContext>()
where TObjectContext : ObjectContext, new();
}
public abstract class BaseDAO<TObjectContext, TEntity> : IBaseDAO<TObjectContext, TEntity>
where TObjectContext : System.Data.Objects.ObjectContext, new()
where TEntity : System.Data.Objects.DataClasses.EntityObject {
private ObjectContextManager _objectContextManager;
/// <summary>
/// Returns the current ObjectContextManager instance. Encapsulated the
/// _objectContextManager field to show it as an association on the class diagram.
/// </summary>
private ObjectContextManager ObjectContextManager {
get { return _objectContextManager; }
set { _objectContextManager = value; }
}
/// <summary>
/// Returns an ObjectContext object.
/// </summary>
protected internal TObjectContext ObjectContext {
get {
if (ObjectContextManager == null)
this.InstantiateObjectContextManager();
return ObjectContextManager.GetObjectContext<TObjectContext>();
}
}
/// <summary>
/// Default constructor.
/// </summary>
public BaseDAO() { }
/// <summary>
/// Instantiates a new ObjectContextManager based on application configuration settings.
/// </summary>
private void InstantiateObjectContextManager() {
/* Retrieve ObjectContextManager configuration settings: */
Hashtable ocManagerConfiguration = ConfigurationManager.GetSection("ObjectContextManagement.ObjectContext") as Hashtable;
if (ocManagerConfiguration != null && ocManagerConfiguration.ContainsKey("managerType")) {
string managerTypeName = ocManagerConfiguration["managerType"] as string;
if (string.IsNullOrEmpty(managerTypeName))
throw new ConfigurationErrorsException("The managerType attribute is empty.");
else
managerTypeName = managerTypeName.Trim().ToLower();
try {
/* Try to create a type based on it's name: */
Assembly frameworkAssembly = Assembly.GetAssembly(typeof(ObjectContextManager));
Type managerType = frameworkAssembly.GetType(managerTypeName, true, true);
/* Try to create a new instance of the specified ObjectContextManager type: */
this.ObjectContextManager = Activator.CreateInstance(managerType) as ObjectContextManager;
} catch (Exception e) {
throw new ConfigurationErrorsException("The managerType specified in the configuration is not valid.", e);
}
} else
throw new ConfigurationErrorsException("ObjectContext tag or its managerType attribute is missing in the configuration.");
}
/// <summary>
/// Persists all changes to the underlying datastore.
/// </summary>
public void SaveAllObjectChanges() {
this.ObjectContext.SaveChanges();
}
/// <summary>
/// Adds a new entity object to the context.
/// </summary>
/// <param name="newObject">A new object.</param>
public virtual void Add(TEntity newObject) {
this.ObjectContext.AddObject(newObject.GetType().Name, newObject);
}
/// <summary>
/// Deletes an entity object.
/// </summary>
/// <param name="obsoleteObject">An obsolete object.</param>
public virtual void Delete(TEntity obsoleteObject) {
this.ObjectContext.DeleteObject(obsoleteObject);
}
public void Detach(TEntity obsoleteObject) {
this.ObjectContext.Detach(obsoleteObject);
}
/// <summary>
/// Updates the changed entity object to the context.
/// </summary>
/// <param name="newObject">A new object.</param>
public virtual void Update(TEntity newObject) {
ObjectContext.ApplyPropertyChanges(newObject.GetType().Name, newObject);
ObjectContext.Refresh(RefreshMode.ClientWins, newObject);
}
public virtual TEntity LoadByKey(String propertyName, Object keyValue) {
IEnumerable<KeyValuePair<string, object>> entityKeyValues =
new KeyValuePair<string, object>[] {
new KeyValuePair<string, object>(propertyName, keyValue) };
// Create the key for a specific SalesOrderHeader object.
EntityKey key = new EntityKey(this.ObjectContext.GetType().Name + "." + typeof(TEntity).Name, entityKeyValues);
return (TEntity)this.ObjectContext.GetObjectByKey(key);
}
#region IBaseDAO<TObjectContext,TEntity> Members
public bool validation(TEntity newObject) {
return newObject.GetType().Name.ToString() == "Int32";
}
#endregion
}
Without knowing how you are instantiating your ObjectContext, I'll throw something in the answer bucket here.
This is how I do my Entity Framework commands and connections (for small simple projects at least):
using (MyEntities context = new MyEntities())
{
return context.getCategoriesStructure();
}
You can also optionally pass in a connection string when instantiating your context (if not, it will use the one in your app.config):
new MyEntities("...connection string...")
If this does not help your issue, please help us understand your code a little better by posting how you are creating your ObjectContext. You could at least attempt to do it this way to see if it works; that will tell you whether it is an issue with your connection string or not.

Categories

Resources