Entity Framework - Code First - Multiple projects - asp.net-mvc

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?

Related

Cannot connect to my edmx with my data context

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?

My model is recognized by my controller, but not my view

I am working on an MVC project and I added a model to my Model's Folder.
[ProjectName].web.Models.ProductAndClient
That same folder already has another model called 'UserAccount'
When I go to my controller, I can instantiate and use the model normally; I didn't have any issues accessing or seeing the model from the controller.
However, when I go to my view and try to use the model with Razor, it will only show the
[ProjectName].web.Models.UserAccount
option. It will not pull up ProductAndClient. I have other classes in the bll that I can access, as well. Is is just this one class that the View will not see.
I already tried the web config solution in this Stack Overflow solution. It didn't work. Again, the view can already see the model folder, it just wont see the one file.
I have also tried building, cleaning, and rebuilding the solution. I have tried shutting down and restarting Visual Studio. I have tried shutting down and restarting my computer. I have tried deleting and re-creating the class. And I have tried accessing the class from other views. And I triple checked everything says 'public'. None of them work.
As far as the exact 'error', when I type the
#model [projectName].web.Models.ProductAndClient
The 'ProductAndClient' part has a red squiggly under it. And it says that it does not exist in the namespace. I have used this syntax on several other pages in this project and other projects, so It must just be some random thing I did to make this not work.
namespace [projectName].web.Models
{
public class ProductAndClient
{
public ClientInv Client { get; set; } //used as a model for the UI
public List<ClientInv> Clients { get; set; } //collected info
public List<ProductCommon> Products { get; set; } //used to compare description and prices
public List<SelectListItem> ProductNames { get; set; } //used for drop down
}
}
using [projectName].web.Models;
namespace [projectName].web.Controllers
{
public class InvoiceController : Controller
{
public ActionResult Index()
{
//Variables
ProductCommon productCommon = new ProductCommon();
List<string> productNames_String = new List<string>();
ProductAndClient client = new ProductAndClient();
//Other code that does stuff goes here
client.Client = new ClientInv();
client.ProductNames = productNames;
client.Products = products;
return View(client);
}
#model [projectName].web.Models.ProductAndClient
If closing/opening the file doesn't help, try adding a using.
#using [projectName].web.Models
#model ProductAndClient
Or add your model namespace to your web.config
<pages>
<namespaces>
<add namespace="[projectName].web.Models" />
</namespaces>
</pages>

how to modify a DbSet at an specific time?

I am working on an ASP NET MVC 5 website and I want to modify an element of a DbSet only once at the start of a new day, month and year, but I can't find any example on the internet doing this, any help on how to do this?
lets say I have:
public class File
{
public int FileID { get; set; }
public int Votes { get; set; }
}
and
public DbSet<File> Files { get; set; }
and I want to change a file votes to 0 at the start of a new day only once:
var modFile = new File{ FileID = 2, Votes = 0};
db.Entry(modFile).State = EntityState.Modified;
db.SaveChanges();
Where in a MVC 5 project do I put this code?
How it gets triggered?
If you have an external Service layer (that is independent of .NET) which contains your objects (in your case, File.cs, etc..) then using the built-in Windows scheduler is fine (it triggers executable code at a certain time, as defined by the user).
To do this, you may want to create a Console Application that has a reference to the Service dll and the connection of your database.
Console Application
In Visual Studio, go to File -> New Project -> Visual C# -> Console Application.
Within the App.config file, you can add the connection string to your database. For example:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<connectionStrings>
<add name="SchoolDBConnectionString"
connectionString="Data Source=...;Initial Catalog=...;Integrated Security=true"
providerName="System.Data.SqlClient"/>
</connectionStrings>
</configuration>
You can then set up a reference to your Service.dll which should have the database context accessible, e.g. DataContext db = MyService.Data.DataContext();
So instead of:
var modFile = new File{ FileID = 2, Votes = 0};
db.Entry(modFile).State = EntityState.Modified;
db.SaveChanges();
You could use:
db.Files.Where(s => s.Votes > 0).ToList().ForEach(s => s.Votes = 0);
db.SavesChanges();
You can run the project in release mode and grab the relevant dll's and exe file. Within the Task Scheduler you are then able to create a task that runs a specific exe.
Service
Technically speaking, you don't have to have this level of isolation -- but in my opinion it's good practice. You could just create a reference to your MVC project, but I personally wouldn't.
To create a Service layer..
Right click your solution (where your MVC application is within) -> Add -> New Project -> Visual C# -> Class Library
Within this project, you should move all your objects (File.cs, etc) within here. You are then able to create a reference to this project within your MVC project by right clicking References and selecting the Service library you just created. You can do the same for the Console Application.
This will then create a layer of isolation between your MVC application and concrete (business) logic.
Otherwise, if you have to schedule your tasks within ASP.NET check out Scott Hanselman's post -- he has compiled together a list of libraries that schedule jobs at certain times. It's however important to understand that ASP.NET applications should only really deal with user requests and responses - threads are somewhat dangerous.

Code-first always working with SQL Server Express or SQL Server CE

I'm building a MVC 3 application and use Entity Framework 4.3 code-first. My context is becoming complex so I've decided to working with SQL Server 2008 R2. Then I changed my connection string in web.config. I checked and I know the new connection string is correct, but EF is still working with the default connection string (.\SQLEXPRESS ...) from SQL Server CE (I have now deleted SQL Server CE from nuget packages).
My context name is CodeFirstContext and my connection string name is CodeFirstContext, too. But the return context.Products; always fails and/because the connection string in context says SQLEXPRESS (my web.config sets the connection string to SQLSERVER).
What is going on here? I erased all default connection strings in the project. When I am running the project, it still gets all data from SQL Server Express.
I have been searching for about two days. Why is this so difficult if so many people only have to change the connection string and then it works.
You might be picking up the connection string from your root/machine config, in your web.config file add a clear element like so
<connectionStrings>
<clear/>
.. your connection strings here
...
I 've solved the problem like that:
public class CodeFirstContext : DbContext
{
public CodeFirstContext() : base("RandevuIzle")
{
}
public DbSet<User> Users { get; set; }
}
<connectionStrings>
<add name="RandevuIzle" connectionString="Data Source=111.222.333.444\MSSQLSERVER2008; Initial Catalog=RandevuIzle;User Id=MyUserName;Password=myPassword" providerName="System.Data.SqlClient" />
Somethings went wrong but i cannot understand. I re-start the project after doing this code below. Then it's work normally.
As you instantiate your DbContext, are you providing a name that isn't CodeFirstContext?
Holy SQL Smoke, Batman! This drove me totally batty today. Getting EF 5.0 up and running w/ VS2010 on a new project was much more difficult than I imagined. I had the same problem and found this great Ode to the Code ::
http://odetocode.com/blogs/scott/archive/2012/08/15/a-troubleshooting-guide-for-entity-framework-connections-amp-migrations.aspx
And to be specific ::
public class DepartmentDb : DbContext
{
public DepartmentDb()
: base(#"data source=.;
initial catalog=departments;
integrated security=true")
{ }
public DbSet<Person> People { get; set; }
}
Got me the result I was needing. Do I think it's cool that I've got to set the data source like this and that it won't find the obvious solution within the app.config? No, I don't. But I have officially spent too much time attempting a transition from LINQ to SQL over to EF today and am going to go ahead and get some of the application done while I still have some interest in doing so.

Entity Framework Code First Doesn't Generate Database

I created a db Context class and added a connection string in my web.config file as instructed in Scott Guthrie's Code First Development with Entity Framework 4. I am running it from a test method. I received several database errors running the tests, but when I finally cleaned up the classes so the test succeeded, I still had no database in the App_data folder.
I added Database.CreateIfNotExists() to the dbContext constructor, but still no sdf file. Anyone know what I am doing wrong?
For the database to be automatically created, the connection string name has to be named exactly as the DbContext subclass name (with namespace).
Eg. Say your DB class is like this:
namespace MyNamespace
{
public class FooDb : DbContext
{
public DbSet<XXX> ABC{ get; set; }
}
}
Your connection string should look like so:
<connectionStrings>
<add name="MyNamespace.FooDb" connectionString="Data Source=|DataDirectory|MyNamespace.FooDb.sdf" providerName="System.Data.SqlServerCe.4.0"/>
</connectionStrings>
Check SQL Server Management Studio -> .\sqlexpress
That's where CF has been putting all my databases when I don't specify a connection string.
See here for auto-creating the .sdf with EF 4.1 and the SQL CE NuGet package (or a new MVC 3 project apparently):
http://www.goatly.net/2011/6/27/entity-framework-code-first-the-path-is-not-valid-check-the-directory-for-the-database.aspx
Long story short: Create an empty App_Data folder - the sdf is auto created, but only if the folder it goes in is present.
Make sure your dbcontext using correct connection string
Some thing similar like this
public class DBContext : IdentityDbContext<ApplicationUser>
{
public DBContext ()
: base("DefaultConnection", throwIfV1Schema: false)
{
}
}
And in web.config
<add name="DefaultConnection" connectionString="Server=....;Connection Timeout=300;" providerName="System.Data.SqlClient" />

Resources