i am trying to build an asp.net mvc 2 app for data entry. I want to generate the views on the forms dynamically so will be using htmlhelpers . What would be the most flexible option for the datasource ? so when i change the database i dont have to actually change the code at all(so i guess EF is not an option)? so no model/controller changes etc. Or i don't have a choice but changing the models in my code?
Well by change database, i assume you mean change dbms, from sql server to oracle for example.
I doubt you'll find a solution to do this without any code changes at all, but you can make things a lot simpler by using interfaces for all you services.
For example
public interface IDataRepository
{
...
}
public class SqlServerDataRepository : IDataRepository
{
...
}
and for testing
public class MockRepository : IDataRepository
{
...
}
and later if you swith databases
public class OracleRepository : IDataRepository
{
...
}
This could then be used simple by referring to interfaces
public class MyService
{
public MyService(IRepository repo)
{
//ctor
{
}
And ideally injecting objects with Inversion of control, Ninject or structuremap for example.
Apologies if this is all already know to you and your looking for something different!
Related
I have some .NET Core code that does some bulk loading of the DB with random sample data.
I'm getting 20 inserts/second on localhost, and looking to improve my performance. I'm doing the basic stuff like calling _dbContext.SaveChanges() only once, etc.
A number of posts like this indicate gains can be had by manipulating properties on the DbContext's Configuration, such as Configuration.AutoDetectChangesEnabled and Configuration.ValidateOnSaveEnabled.
My .NET Core MVC app's DbContext is a subclass of IdentityDbContext, which does not expose the Configuration.
Not sure what approach I should be using - can I / should I be messing with those configuration properties of a IdentityDbContext subclass?
Or, should I use a separate DbContext for this? (Some early research indicated the typical pattern is a single DbContext for a webapp).
There is no need for creating separated DbContext class and you can turn change tracking off:
context.ChangeTracker.AutoDetectChangesEnabled = false;
or you can turn it off globaly:
public class MyContext : IdentityDbContext
{
public MyContext()
{
ChangeTracker.AutoDetectChangesEnabled = false;
}
}
I need guidance on designing data layer for my Web API services. The Web API controllers call the service layer which calls the data layer.
I am planning to use Entity Framework along with Dapper. It might not be a good solution to use both of them together, but I need both. I need EF as it is easier to use and developers in my team are familiar. I need Dapper for performance. So, it will be a mix depending on where the dapper can make significant impact and where we can compromise on being a little late.
When using EF, I wanted to use unit of work with repository for each entity. My repository will be like
public class StudentRepository : IStudentRepository, IDisposable
{
private SchoolContext context;
public StudentRepository(SchoolContext context)
{
this.context = context;
}
public IEnumerable<Student> GetStudents()
{
return context.Students.ToList();
}
}
I took that sample code from http://www.asp.net/mvc/overview/older-versions/getting-started-with-ef-5-using-mvc-4/implementing-the-repository-and-unit-of-work-patterns-in-an-asp-net-mvc-application
So, now I wanted to introduce Dapper.
Approach 1: Initially I thought of having multiple repositories for Dapper and for Entity Framework and I can register the one which I need in my dependency injection container. But in this case, all the methods from IStudentRepository interface needs to be implemented in both the EF and Dapper concrete repository classes (if I could do this in Dapper completely, then I don't need EF at all).
Approach 2 : Then I thought about a more ugly approach and it is like exposing a property of IDbConnection along with the DbContext property (in this case SchoolContext) in the above StudentRepository class.
So the example would be like
public class StudentRepository : IStudentRepository, IDisposable
{
private SchoolContext context;
private IDbConnection Db;
public StudentRepository(SchoolContext context)
{
this.context = context;
this.db = new SqlConnection(ConfigurationManager.ConnectionStrings["conn"].ConnectionString);
}
public IEnumerable<Student> GetStudents()
{
return context.Students.ToList();
}
public IEnumerable<Student> GetStudentsBasedOnSomeComplexCondition()
{
//I can use the db property here and work with dapper in this case.
}
(The inclusion of the IDbConnection property can be done through an abstract class so as not to repeat the instantiation code of this property and to easily change the connection string in case if needed. I am adding it in the same class for simplicity).
Approach 3 : Now, I thought of separating it further which I again think is an ugly way. Along with StudentRepository which has only EF stuff (like the first example), I will have another concrete class called StudentDapperRepository which inherits from StudentRepository.
All the methods in StudentRepository will be changed to virtual. So, I will be using StudentDapperRepository for my actual data layer and this will have the Dapper implementations where needed and where not needed, it will use the base class StudentRepository methods (which is in EF).
I think all my solutions are ugly and adding more complexity and confusion. So, can I have some light into how I can do this.
I am playing around building some buildingblocks based on database tables.
So I've created an UsersManager and a ValidationManager both based on the EDMX "templates".
I'd really like to loose couple those two components with MEF. But therefore i need to create Interfaces of the entityobjects exposed in the ValidationManager.
Is there an easy way of creating those Interfaces, in that manner i can still use the EDMX generated classes?
Thanx,
Paul
Using an example of a database with a Product Table, is this what you're trying to achieve....
but still use generated entity classes (using either the standard EF generator or another POCO generator of some sort).
I'm not sure - as you mention MEF and I don't see it being directly related.
The generated entity classes are partial classes which will allow you to extend the generated class which in this case you want to extend to implement an interface.
Presuming the following interface is going to be used to introduce the layer of abstraction...
public interface IEntity {
public bool IsDeleted { get; set; }
}
Create a new class file with and extended Product class...
public partial class Product : IEntity {
public bool IsDeleted {
get {
throw new NotImplementedException();
}
set {
throw new NotImplementedException();
}
}
}
You have now extended your generated entity Product with the partial class custom code - and you can use it as normal through EF.
Now instead of your UserManager and ValidationManager classes having a hard reference to Product, instead they'll only have reference to IEntity.
If I didn't understand the question, please provide more details on exactly it is you want to do.
Suppose I have some Interface like :
public interface IIconComponent
{
// statements ...
}
then I am implementing this interface within my class as below
public class IconComponent : IIconcomponent
{
// implementing the interface statements ..
}
and creating a Table in mvc3 like:
public class IconDBContext : DbContext
{
public DbSet<IIconComponent> Icon {get; set;} //Is this statement possible
}
That is making the set of objects of interface type for storing the class IconComponent objects in the table. How to do this in MVC3 ?
Does I have to implement some model-binder for this ? or, there exists some other method ?
Thanking you,
EF doesn't support interfaces. DbSet must be defined with the real implementation. Once you change it to use implementation your actions will most probably use it as well because there will be no reason to work with abstraction.
Why would you use entity framework is you're creating abstraction layer on top of it, it's as you're not using entity framework at all and because of that entity framework is not able to work with interfaces.
If you really need to, you can let your Entity Framework classes implement interfaces. With POCO's it's straightforward, with edmx you can make partial classes that contain the derivation from the interface. However, as said by Ladislav, something like DbSet<IIconComponent> is not possible.
I can imagine scenarios where you would want to use this, e.g. dealing with other application components that only accept specific interfaces, but that you want to populate with your EF classes. (The other day, I did exactly that with a legacy UI layer).
When using the examples for Single Page Application, I've the following TodoItem controller:
public partial class MVC4TestController : DbDataController<MVC4TestContext>
{
public IQueryable<TodoItem> GetTodoItems()
{
return DbContext.TodoItems.OrderBy(t => t.TodoItemId);
}
}
Question 1:
It seems that only EntityModels are supported ?
When using a real ViewModel (model only used for the Views, not not used as 1:1 mapping to database entity), the DbDataController does not support this.
Also using Linq.Translations or PropertyTranslator does not seem to work, see this code extract:
private static readonly CompiledExpressionMap<TodoItem, string> fullExpression =
DefaultTranslationOf<TodoItem>.Property(t => t.Full).Is(t => t.Title + "_" + t.IsDone);
public string Full
{
get
{
return fullExpression.Evaluate(this);
}
}
Question 2:
What is the recommended design when using SPA, DBContext and ViewModels ?
As far as I know so far is - it instists on the usage of "real" model classes bound to DbContext.
I have the same problem as you - I need to use my own DTO objects which are "flat".
The Json serialisation is currently not able to serialize data which has parent references in child objects (cyclic references). Usually I do not need the entity tree anyways so I created smaller classes which fits perfectly to the view.
I tried to use a normal Controller with JsonResult and parsed the returned model into ko.mapping.fromJS after retrieved the data. Thats working fine. But - you have to take care of all the nice stuff the MVC4 generated viewmodels are already dealing with (like creating navigation, etc.).
Maybe someone finds a workaround to "fake" a DbContext with DTO data.