Cannot connect to my edmx with my data context - asp.net-mvc

I've not used VS MVC for a while but I'm writing a project which requires connecting to a Sql database which I've installed as an edmx file SwitchDB.edmx in my DAL folder. In the past I've set up my data context file which I then use to reference the data in my controller, the model help me to order the data in the correct way.
This is how my data context file looks
namespace Switches.DAL
{
public class SwitchContext : DbContext
{
public SwitchContext()
: base("DefaultConnection")
{ }
public DbSet<Switch_List> SwitchList { get; set; }
}
}
I've set up the "DefaultConnection" in my Web.config under connectionStrings and my model Switch_List.cs has the file settings. When I declare the DB context in my controller as below
private SwitchContext db = new SwitchContext();
Then I would expect to reference the SwitchContext to get my data, like this
var switches= db.SwitchList .ToList();
However, when I run the project and reference db in debug I get the following error message 'the function evaluation requires all threads to run'. The DB context SwitchContext is clearly not getting access to the Switch.edmx so what am I forgetting?

I had a similar problem, but you should see the connection properties using an IDE button (to re-evaluate the expression).
However, when you get to the part of db.SwitchList.ToList() does it generate any exceptions?

Related

How to update database programmatically from mvcArea

I'm using EF6 Code First Migrations for Multiple Models means working with a single database via multiple dbContext and Migrations, In MVC5!
Why?
Because i want to add new Entities to database from my Areas!..So each Area have their own dbContext and Migrations Files. i use Update-Database command in console package manager and my database will update without any problem.
As every body knows: You can update your database from each projects of your solution but if you set it as StartUpProject of solution.
and my challenge is about what i said in above Blockquote ! because in another step i want to update my database programmatically by this code:
//ActionResult of my Area:
public ActionResult Create()
{
var configuration = new Configuration();
var migrator = new DbMigrator(configuration);
migrator.Update(); //got Error in this line
return View();
}
i get
network-related or instance-specific error
in specified line and i know why!..because my Area Project is not set as StartUpProject of my solution and it shouldn't be.
So how can i handle this situation in your view?
I knew. i should give ConnectionString to my configuration instance, straightly like this:
public ActionResult Create()
{
var configuration = new Configuration();
configuration.TargetDatabase = new DbConnectionInfo(
"Server=.;Database=SegalFrameWork;Trusted_Connection=True;",
"System.Data.SqlClient");
configuration.ContextKey = "BlogDbContext";
var migrator = new DbMigrator(configuration);
migrator.Update();
return View();
}
now there is no need to read connection string from web.config so it doesn't need any startup project to find it.

EF migration Seeding with large dataset

I am using EF Code First Migration with ASP.NET MVC5 project. I want to seed the database with about 5000 records. The examples on the asp.net web site and blogs all have the seed function within the configuration method.
internal sealed class Configuration : DbMigrationsConfiguration<foo.ApplicationDbContext>
{
public Configuration()
{
AutomaticMigrationsEnabled = false;
MigrationsDirectory = #"Migrations\ApplicationDbContext";
}
protected override void Seed(foo.ApplicationDbContext context)
{
SeedProducts(context);
SeedFoods(context);
// This method will be called after migrating to the latest version.
// You can use the DbSet<T>.AddOrUpdate() helper extension method
// to avoid creating duplicate seed data. E.g.
//
// context.People.AddOrUpdate(
// p => p.FullName,
// new Person { FullName = "Andrew Peters" },
// new Person { FullName = "Brice Lambson" },
// new Person { FullName = "Rowan Miller" }
// );
//
}
}
What are some options to seed large data sets when using EF Migration?
Currently The configuration file is over 5000 lines long and is different to manage.
I would prefer to store them in another database or excel spreadsheet and then import them in using the seed function. I am not sure how to go about importing data from external sources within the Seed method.
I also tried to break up the data set into several files but when I try to call the function
SeedProducts(context);
SeedFoods(context);
outside of the Configuration Class I get a build error: "The name does not exists in the current context". (I am not sure what this means?
You can store the sql file in the base directory and use it. You can create multiple sql files. I used following code to execute all sql files stored on base directory.
protected override void Seed(CRM.Data.DbContexts.CRMContext context)
{
var sqlfiles = Directory.GetFiles(AppDomain.CurrentDomain.BaseDirectory+"\\initialdata", "*.sql");
sqlfiles.ToList().ForEach(x=> context.Database.ExecuteSqlCommand(File.ReadAllText(x)));
}
Why we need to have a seed data for 5000 records. If you prefer this way it will take lot of manual work also. where as, its not required here.
Instantly you can Create Scripts and execute that into you db. via Code as well as Manually.
Db Scripts can be taken for entire db as well as each table, Store Procedure wise also. So, that you will get records particularly.
Follow the steps from this link OR MSDN
Note: After Creating the Database Script. You can read the file from Seed Function and Execute the query from function itself. Or Manually you can go and execute when ever you need it.
I ended up using a CSV (comma delimited file) and storing it as a domain resource. Then reading the CSV file and adding database records:
I am able to Seed the database using EF Migration Seed method and a CSV file as defined as follows in the Migration.cs file. Note: the CSV file in the project in Visual Studio are set to the Build Action to Embedded Resource.
public void SeedData(WebApp.Models.ApplicationDbContext Context)
{
Assembly assembly = Assembly.GetExecutingAssembly();
string resourceName = "WebApp.SeedData.Name.csv";
using (Stream stream = assembly.GetManifestResourceStream(resourceName))
{
using (StreamReader reader = new StreamReader(stream, Encoding.UTF8))
{
CsvReader csvReader = new CsvReader(reader);
csvReader.Configuration.WillThrowOnMissingField = false;
var records = csvReader.GetRecords<Products>().ToArray();
foreach (Product record in records)
{
Context.Products.AddOrUpdate(record);
}
}
}
Context.SaveChanges();
}

Entity Framework - Code First - Multiple projects

I have one solution with three projects in it:
ToDo.Web
ToDo.Core
ToDo.Data
ToDo.Web is my startup project and is an MVC 4 solution.
ToDo.Core is a Class Library solution and it contains all my classes like User, Task etc.
ToDo.Data is my data repository and contains my ToDoContext model.
My ToDoModel model looks like this:
namespace ToDo.Data
{
public class ToDoModel : DbContext
{
public DbSet<Task> Tasks { get; set; }
public DbSet<User> Users { get; set; }
}
}
I am trying to get the project to create my database on my locally installed SQL Server 2012. So in my web.config (in the ToDo.Web project) I have the following connectionstring:
<add name="ToDo.Data.ToDoModel" connectionString="Data Source=XXX\YYY;Integrated Security=SSPI;initial catalog=ToDo" providerName="System.Data.SqlClient" />
I then try to execute the following command from Package Manager Console:
Enable-Migrations -projectname ToDo.Data -StartUpProjectName ToDo.Web
The command executes nicely with no errors. And I can see a Migrations folder in my ToDo.Data project. But it only contains a Configuration.cs file and no information about my model. And I cannot see the database being created on my SQL server either.
I have tried creating a simple Console application, using the same connection string where it works nicely.
I have tried adding the connection string to my app.config in the ToDo.Data project without luck.
Anyone who can guide me in the right direction?

L2S DataContext out of synch: row not found or changed

Psssst...!
Read on, by all means. But I can tell you here that the problem had nothing to do with the DataContext, but with Dependency Injection. I have left the question up, as it documents one possible issue with the "row not found or changed error" that has nothing to do with real world concurrency conflicts.
It seems the problems have been caused by badly written dependency injection. Or rather, I am beginning to believe, by default lifecycle management by the DI container I used.
The problem was that I used a DataContext as a constructor argument that was supplied by Ninject. It seems that the default behaviour was to cache this DataContext, leading to all manner of unexpected behaviour. I will ask a separate question about this.
Anyway, what follows is my original question, which as you will see, misses the real cause of the issue by a mile...
The Problem
I am getting a number of errors that imply that the DataContext, or rather, the way I am using the DataContext is getting out of synch.
The error occurs on db.SubmitChanges() where db is my DataContext instance. The error is:
Row not found or changed.
The problem only occurs intermitently, for example, adding a row then deleting it. If I stop the dev server and restart, the added row is there and I can delete it no problem.
Ie, it seems that the problem is related to the DataContext losing track of the rows that have been added.
IMPORTANT:
Before anyone votes to close this thread, on the basis of it being a duplicate, I have checked the sql server profiler and there is no "Where 0 = 1" in the SQL.
I have also recreated the dbml file, so am satisfied that the database schema is in synch with the schema represented by the dbml file.
Ie, no cases of mismatched nullable/not nullable columns, etc.
My Diagnosis (for what it is worth):
The problem seems (to me) related to how I am using the DataContext. I am new to MVC, Repositories and Services patterns, so suspect that I have wired things up wrong.
The Setup
Simple eLearning app in its early stages. Pupils need to be able to add and delete courses (Courses table) to their UserCourses.
To do this, I have a service that gets a specific DataContext instance Dependency Injected into its constructor.
Service Class Constructor:
public class SqlPupilBlockService : IPupilBlockService
{
DataContext db;
public SqlPupilBlockService(DataContext db)
{
this.db = db;
CoursesRepository = new SqlRepository<Course>(db);
UserCoursesRepository = new SqlRepository<UserCourse>(db);
}
// Etc, etc
}
The CoursesRepository and UserCoursesRepository are both private properties of the service class that are of type IRepository (just a simple generic repository interface).
SqlRepository Code:
public class SqlRepository<T> : IRepository<T> where T : class
{
DataContext db;
public SqlRepository(DataContext db)
{
this.db = db;
}
#region IRepository<T> Members
public IQueryable<T> Query
{
get { return db.GetTable<T>(); }
}
public List<T> FetchAll()
{
return Query.ToList();
}
public void Add(T entity)
{
db.GetTable<T>().InsertOnSubmit(entity);
}
public void Delete(T entity)
{
db.GetTable<T>().DeleteOnSubmit(entity);
}
public void Save()
{
db.SubmitChanges();
}
#endregion
}
The two methods for adding and deleting UserCourses are:
Service Methods for Adding and Deleting UserCourses:
public void AddUserCourse(int courseId)
{
UserCourse uc = new UserCourse();
uc.IdCourse = courseId;
uc.IdUser = UserId;
uc.DateCreated = DateTime.Now;
uc.DateAmended = DateTime.Now;
uc.Role = "Pupil";
uc.CourseNotes = string.Empty;
uc.ActiveStepIndex = 0;
UserCoursesRepository.Add(uc);
UserCoursesRepository.Save();
}
public void DeleteUserCourse(int courseId)
{
var uc = (UserCoursesRepository.Query.Where(x => x.IdUser == UserId && x.IdCourse == courseId)).Single();
UserCoursesRepository.Delete(uc);
UserCoursesRepository.Save();
}
Ajax
I am using Ajax via Ajax.BeginForm
I don't think that is relevant.
ASP.NET MVC 3
I am using mvc3, but don't think that is relevant: the errors are related to model code.
The problem only occurs intermitently,
for example, adding a row then
deleting it. If I stop the dev server
and restart, the added row is there
and I can delete it no problem.
Your code does not show what the link is between the Added Row and the Delete/Update. Your Add() doesn't return an object reference.
I'm thinking you are missing a Refresh (ie reload the object after Insert). Is your IdCourse also the PK in the Table?
Edit:
Further research has revealed that the problem is with the dependency injection.
The problem was related to how Dependency Injection manages the items it creates. Google for 'lifecycle management' in IoC or DI. Essentially, DI cached a DataContext constructor argument that I injected.
For a way to solve this using the Factory Pattern, see this thread:
Ninject caching an injected DataContext? Lifecycle Management?
The accepted answer solved it all.

DataContext crashes when unit testing

I am using Linq to SQL in my project. I have a part of the code that calls
DataContext db = new DataContext()
This works as expected when running the website however when calling this from within my unit test I get an error object not set to an instance...
Do you know why this is?
I know I should Mock the data context for testing but there is only two tests that use this that I need completed for this stage of the project. Then I will go in and Mock.
I just don't see why it doesn't work.
Edit:
In my controller I have the line
CandidateRegistrationViewModel viewModel = new CandidateRegistrationViewModel("PersonalDetails", candidate);
The Model has a member db:
public class CandidateRegistrationViewModel
{
private EmployDirectDataContext db = new EmployDirectDataContext();
This class then uses db to populate select boxes.
It all works when I run but in the unit test I get an error upon creating the datacontext.
[TestMethod]
public void PersonalDetailsStepPostShouldRedisplayIfDOBSuppliedInWrongFormat()
{
// Arange
var controller = CreateCandidateController("Dean");
repository.Add(FakeCandidateData.CreateCandidate(controller.member.UserId()));
FormCollection formCollection = FakeCandidateData.CreatePersonalDetailsStepFormCollection();
formCollection["DOB"] = "24/2009/87"; //DOB in wrong format - should be dd/mm/yyyy
controller.ValueProvider = formCollection.ToValueProvider();
// Act
ViewResult result = (ViewResult)controller.PersonalDetailsStep(formCollection);
// Assert
Assert.AreEqual("", result.ViewName); //ViewName is returned as empty if same as Action name
}
Both of the projects have the same connection string in the app/web.config
<add name="EmployDirectDBConnectionString" connectionString="Data Source=.\SQLEXPRESS;AttachDbFilename=|DataDirectory|\EmployedDirectDB.MDF;Integrated Security=True;User Instance=True"
providerName="System.Data.SqlClient" />
Testing the Data Context falls more into the purview of an Integration Test. The mocks are more appropriate for your repository interface. Your repository will hold a valid reference to the DataContext object during your integration testing.
Your unit test assembly probably does not have the right connectionstring compiled into the settings. That's why I always use:
var db = new MyDataContext(SomeConfigClassIMade.ConnString) {...}
so I can more tightly control how the connection string works,.
I an not sure why you would want to test the DataContext itself... (I may be wrong and I am sure someone will tell me if I am) but would you just test the DataAccess or Repository class that uses the DataContext...
Other than that it probably just doesn't have the correct connection string...

Resources