Type used in a using statement must be explicitly convertible to 'System.IDisposable' - entity-framework-6

Using Entity Framework and Devart Entity Developer on an existing database. I brought the table needed into the Entity Designer model using the wizard. Saved the model - that creates the underlying code for EF. Now when I try to use:
using (Document ctx = new Document())
{
}
I get the error:
CS1674 'Document': type used in a using statement must be implicitly convertible to 'System.IDisposable' or implement a suitable 'Dispose' method.
I have seen posts that suggest that state to make sure that Entity Framework is added as a NuGet package - it is. I have use Entity Designer before in this situation but did not run into this issue.
Any ideas?
Edit
Document:
public partial class Document : EntityObject {//...
EntityObject:
namespace System.Data.Entity.Core.Objects.DataClasses
{
/// <summary>
/// This is the class is the basis for all perscribed EntityObject classes.
/// </summary>
[DataContract(IsReference = true)]
[Serializable]
public abstract class EntityObject : StructuralObject, IEntityWithKey, IEntityWithChangeTracker, IEntityWithRelationships
{

Related

Created DbConfiguration dynamically in EF6

I'm using EF 6.4.4 in .NET 5, and want to associate a MyDbConfiguration with a MyDbContext. However, the only way to do this appears to declare MyDbContext with a DbConfigurationType attribute. For example:
[DbConfigurationType(typeof(MyDbConfiguration))]
public class MyContextContext : DbContext
{
}
But an attribute is static, and I need to create MyDbConfiguration dynamically, via a dependency injection framework. Is there any way to do this?

Asp Identity Custom context

I am building a single page application, so I used the visual studio default template.
When It was on development I had 2 databases Entityframework.mdf and Identity.mdf, because thats what the default configuration does, but now I need relation ship with the users and I can't reach them easly because they are in another database.
in an MVC template you can easly do it like this:
public class ApplicationUser: IdentityUser
{
}
public class ApplicationDbContext : IdentityDbContext<ApplicationUser>
{
public ApplicationDbContext()
: base("DefaultConnection")
{
}
public DbSet<CustomTableItem> CustomTable{ get; set; }
//You can add more tables
}
when you use the single page application it configures the user management in a way I don't understand.
UserManagerFactory = () => new UserManager<IdentityUser>(new UserStore<IdentityUser>());
then from this article
This code uses the default constructor for the UserStore class, which will create a new instance of an IdentityDbContext object since an object isn’t supplied. If you want to use your own IdentityDbContext derived class, like the MVC 5 project does, you can modify the above initialization code and pass in your own context.
it says I can modify it but it does not show how :(, and I have tried but I can’t make it work. This is what I am trying to do
UserManagerFactory = () => new UserManager<ApplicationUser>(new UserStore<ApplicationUser>());
what am I missig?
If you use default constructor (with not parameters) for UserStore class, this happens:
public UserStore()
{
this..ctor((DbContext) new IdentityDbContext());
this.DisposeContext = true;
}
Identity framework creates it's own database context for you with default connection string and no relation to your own models or DbContext.
What Scott says in his article is that UserStore has a constructor defined like this:
public UserStore(DbContext context)
{
base..ctor(context);
}
In other words you can supply your DbContext as a parameter into the constructor of UserStore:
UserManagerFactory = () => new UserManager<ApplicationUser>(
new UserStore<ApplicationUser>(new ApplicationDbContext()))
Where ApplicationDbContext is defined as you describe in the question.
You'll need to create a migration on ApplicationDbContext that will create Identity tables in Entityframework.mdf. Then you'll have to move data from Identity.mdf into your main database. Connect to both datbases and run something like this:
insert into EntityFramework.dbo.IdenetityUsers
select * from Identity.dbo.IdentityUsers
However, I've only done data migration from one DB to another one within single SQL Server instance, not between LocalDbs (I presume you used these). So this method might not work and you'll have to export data from Identity.mdf into csv files and import them into EntityFramework.mdf

Make JSON.NET and Serializable attribute work together

I'm using JSON.NET and had some troubles in the past during WEBAPI objects deserialization. After doing some research I've found that the class was marked with [Serializable]. When I removed this the deserialization was just fine.
More detailed information about this can be found here:
Why won't Web API deserialize this but JSON.Net will?
Now it comes to the problem that I use binaryformatter to create a hash value calculated from this object class.
But Binaryformatter requires that the class must be marked as [Serializable].
Could you recommend me any approach to make both things work at the same time?
Found the solution:
First, check that your Newtonsoft.JSON version is greater than 4.5 or just update with NuGET
According to the version notes, both can work together starting from this version using some extra annotations.
http://james.newtonking.com/archive/2012/04/11/json-net-4-5-release-2-serializable-support-and-bug-fixes
"Now if you are serializing types that have the attribute and don’t want the new behaviour, it can either be overridden on a type using the JsonObjectAttribute"
[JsonObject]
[Serializable]
public class Foobar {
Now it is possible to use JSON.NET and, in my case, the binaryformatter with the [Serializable] attribute.
An alternative to specifying JsonObject on each class is to tell web.api to ignore Serialize attributes globally. This can be done by resetting the DefaultContractResolver on the web api JsonFormatter:
config.Formatters.JsonFormatter.SerializerSettings.ContractResolver = new DefaultContractResolver();
(using NewtonSoft.Json.Serialization where config is the System.Web.Http.HttpConfiguration)
As of NewtonSoft v4.5 the IgnoreSerializableAttribute property on the DefaultContractResolver is set to true but the web api wrapper, around DefaultContractResolver, has this set to false by default.
I was using a POCO with Serializable attribute. In the first case while Posting Request to a WebApi worked by using the following method:
JsonMediaTypeFormatter f = new JsonMediaTypeFormatter()
{
SerializerSettings = new JsonSerializerSettings()
{
ContractResolver = new DefaultContractResolver()
{
IgnoreSerializableAttribute = true
}
}
};
var result = client.PostAsJsonAsync<IEnumerable<Company>>("company/savecompanies", companies).Result;
//I have truncated the below class for demo purpose
[Serializable]
public class Company
{
public string CompanyName {get;set;}
}
However, when I tried to read the response from WebApi (Which was posted back as JSON), the object was not properly deserialized. There was not error, but property values were null. The below code did not work:
var readObject = result.Content.ReadAsAsync<IEnumerable<Company>>().Result;
I read the documentation as given on Newtonsoft.Json website https://www.newtonsoft.com/json/help/html/SerializationAttributes.htm and found the following and I quote from that site:
Json.NET attributes take precedence over standard .NET serialization
attributes (e.g. if both JsonPropertyAttribute and DataMemberAttribute
are present on a property and both customize the name, the name from
JsonPropertyAttribute will be used).
So, it was clear if Newtonsoft.Json attributes are present before the standard .NET attributes they will take precedence. Hence I could use the same class for two purposes. One, when I want to post to a WebApi, Newtonsoft Json serializer will kick in and Two, when I want to use BinaryFormatter.Serialize() method std .NET Serializable attribute will work.
The same was confirmed with the answer given above by #Javier.
So I modified the Company Class as under:
[JsonObject]
[Serializable]
public class Company
{
public string CompanyName {get;set;}
}
I was able to use the same class for both purposes. And there was no need for the below code:
JsonMediaTypeFormatter f = new JsonMediaTypeFormatter()
{
SerializerSettings = new JsonSerializerSettings()
{
ContractResolver = new DefaultContractResolver()
{
IgnoreSerializableAttribute = true
}
}
};

Entity Framework Generic Repository Implementation with IQuarable

Entity Framework has changed drastically since they have introduced version 1. EF 4.1 has improved Code First and Fluent mappings which are really impressive. However, I have a worry about complex query implementations on EF 4.1 because it depends on DbContext strongly. Entity SQL and Linq to Entities keep on changing it's behavior with SQL queries. I feel we need a strong Query mechanism like HQL or Criteria to overcome this. What you think ?
Many modern .NET ORMs provide an IQueryProvider implementation (including NHibernate). I choose to remove the direct dependency on EF by using POCO T4 template, then modifying it to generate an interface (IMyRepository) that returns plain IQueryables instead of ObjectSets. The underlying implementation of IMyRepository using a ObjectContext. If we decide to move away from EntityFramework, we can just change the implementation of IMyRepository to use someone else's LINQ IQueryProvider.
Further, this allows us to work in a distributed scenario. For example, one implementation of IMyRepository lives on the client and uses DataServiceClient (WCF Data Services) to call out to the server, which has a different implementation of IMyRepository, which uses Entity Framework directly.
In the case of Code First, this is also fairly easy to do. Your classes are already POCOs...so just make your DbContext implement an interface that returns IQueryables instead of DbSets.
I personally then inject the IMyRepository using dependency injection.
My Generic repository Looks like follows
public class Repository<TEntity, TPrimaryKey>: IRepository<TEntity, TPrimaryKey> where TEntity : class
{
public IQueryable<TEntity> GetQuery()
{
return this.UnitOfWork.GetQuery<TEntity>();
}
public IQueryable<T> LoadType<T>() where T : class
{
return this.UnitOfWork.GetQuery<T>();
}
}
And My Unit of Work goes here
public class UnitOfWork
{
/// <summary>
/// Gets the query.
/// </summary>
/// <typeparam name="TEntity">The type of the entity.</typeparam>
/// <returns></returns>
public IQueryable<TEntity> GetQuery<TEntity>() where TEntity:class
{
return this.DbContext.Set<TEntity>();
}
}

ASP.NET MVC: avoid tight coupling when binding form POST to parameter

Let's say I have an interface like:
interface IThing {
int Id { get; set; }
string Title { get; set; }
}
And in ASP.NET MVC I have a form that posts to a controller action like this:
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult NewThing([Bind(Exclude = "Id")] SimpleThing thing) {
// code to validate and persist the thing can go here
}
Where SimpleThing is a concrete class that just barely implements IThing.
However, I would like all my methods to deal with the interface. I have a data assembly that uses NHiberate and its own IThing implementation (let's call it RealThing). I can't pass the SimpleThing to it because it will complain about an "unknown entity".
Does anyone have any ideas about a cleaner way to do this? I was thinking about something along the lines of using a factory class. But how would I get the MVC form binder to use it?
Thanks!
You can use custom model binders. However article on msdn is totally useless. So better to employ search and find something better. There are planaty of articles available.
I came up with two approaches to this.
The first was to add code to my NHibernate Repository class to translate the simple POCO type used by the MVC controller (SimpleThing) to the type of entity that NHibernate wanted (RealThing):
/// <summary>
/// A NHibernate generic repository. Provides base of common
/// methods to retrieve and update data.
/// </summary>
/// <typeparam name="T">The base type to expose
/// repository methods for.</typeparam>
/// <typeparam name="K">The concrete type used by NHibernate</typeparam>
public class NHRepositoryBase<T, K>
: IRepository<T>
where T : class
where K : T, new()
{
// repository methods ...
/// <summary>
/// Return T item as a type of K, converting it if necessary
/// </summary>
protected static K GetKnownEntity(T item) {
if (typeof(T) != typeof(K)) {
K knownEntity = new K();
foreach (var prop in typeof(T).GetProperties()) {
object value = prop.GetValue(item, null);
prop.SetValue(knownEntity, value, null);
}
return knownEntity;
} else {
return (K)item;
}
}
So, any method in the repository can call GetKnownEntity(T item) and it will copy the properties of the item you pass in to the type that NHibernate wants. Obviously this felt a bit clunky, so I looked in to custom model binders.
In the second approach, I created a custom model binder like this:
public class FactoryModelBinder<T>
: DefaultModelBinder
where T : new()
{
protected override object CreateModel(ControllerContext controllerContext,
ModelBindingContext bindingContext,
Type modelType) {
return new T();
}
}
Then I registered that in Global.asax.cs with:
ModelBinders.Binders.Add(typeof(IThing),
new FactoryModelBinder<RealThing>());
And it works fine with a Controller Action that looks like this:
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult NewThing([Bind(Exclude = "Id")] IThing thing) {
// code to process the thing goes here
}
I like the second approach, but most of my dependency injection stuff is in the Controller class. I don't like to have to add all these ModelBinder mappings in Global.asax.cs.
There were some good suggestions here and I actually came up with a solution that works. However, I ended up with something altogether. I just created models specific for the form data I was posting and used the default model binder.
Much simpler and it allows me to capture data that isn't part of my domain model (ie. like a "comments" field).
This is not dirrect unswer to your question.
We use slightly different approach to deal with same problem you have. Our Controllers accepts DTOs that match persistent entity field by field. Then we user AutoMapper to create persisten entities that will go to the database. This eliminates unnessesery interfaces and locks down public facing API (means that renaming persistance object's field will not break our client code).

Resources