Database error InValidOperationException when attempting to save to database - database

I get this error when I attempt to save to the database.
In the Controller I have the Edit HttpPut
public ActionResult EditSubject(Models.xxxx model)
{
//Database Model Class
SubjectDB subjectdb = new SubjectDB();
// Name of DB Access in Web.config
BeaconDBEntities db = new BeaconDBEntities();
if (ModelState.IsValid)
{
subjectdb.SubjectId = model.SubjectId;
db.SubjectDBs.Add(subjectdb); --> Pops InvalidOperationsException
db.SaveChanges();
}
In Models folder is the model for the database table
SubjectDB.cs
namespace xxx.Models
{
public class SubjectDB
{
public string SubjectId { get; set;}
}
public class BeaconDBEntities: DbContext
{
public DbSet<SubjectDB> SubjectDBs { get; set; }
}
}
Web.config is the connect string for the database
<coneectionStrings>
<add name="BeaconDBEntities" ...............
</connectionStrings>

The first thing I see is that your connection string name 'BeaconDBEntites' does not match your DbContext inherited class name 'BeaconDBEntities' (you are missing an 'i' in the word Entities). Try changing that and see if it fixes it.

When you edit your data then i think you don't need to write code like this when your useing entity framework it's below code
db.SubjecDBs.Add(subjectdb);
db.SaveChanges();
first when you update your data then first your get your data with your id like this it's below
and your create object your entity class. your entity class is your table like below
SubjecDBs objsub=new SubjecDBs();
var data =db.db.SubjecDBs.where(x=>x.SubjectID==ID).ToList();
then you match your data which is you wont to update like below
objsub.SubjecName=data[0].SubjecName
and you match your field which you wont to update then your write below code like this
db.SaveChanges();
i think this will help you...

Related

How to add-migrations for auto-generated databases?

I have an application which contains to context classes. One is master context class and second is sub context class. When I run the application for the first time the master database gets generated. And whenever I create a new user, a database related to that user gets generated using sub context class. For example, if I create 10 users then 10 databases will get generated using sub context class like sub_db_userId.
The problem is enabling migrations in this complex structure. I know some people would say it's not appropriate to create new database use foreign key relation but I have to work on requirements.
I found this thread very helpful in finding how to enable-migrations for separate context classes but in my scenario, it does not apply changes to existing databases because of database name is associated with user ids. Rather applying changes to existing child databases it creates new database without user id like this sub_db_. How can I solve this issue?
The way I am creating the new database for every user is given below.
My context classes:
public class ApplicationDbContext : IdentityDbContext<ApplicationUser>
{
public ApplicationDbContext()
: base("DefaultConnection", throwIfV1Schema: false) {}
}
public class SubDbContext : DbContext
{
public DbSet<Country> Countries { get; set; }
public DbSet<City> Cities { get; set; }
public SubDbContext() : base("SubDatabaseConnection")
{
}
public SubDbContext(string connectionString) : base(connectionString)
{
Database.SetInitializer<SubDbContext>(new
CreateDatabaseIfNotExists<SubDbContext>());
}
}
Connection strings:
<add name="DefaultConnection"
connectionString="Data Source=.\SQLExpress;Initial Catalog=master_db;Integrated Security=True"
providerName="System.Data.SqlClient" />
<add name="SubDatabaseConnection"
connectionString="Data Source=.\SQLExpress;Initial Catalog={0};Integrated Security=True"
providerName="System.Data.SqlClient" />
</connectionStrings>
I am using {0} for formatting purposes. How can I enable migrations and apply changes to existing databases?
Modifications: I am linking tables to database in Register action like this:
SubDbContext newContext = new SubDbContext(string.Format(userDatabase, "sub_db_" + userId));
newContext.Countries.FirstOrDefault();
newContext.Cities.FirstOrDefault();
Your DbContext for all your sub-databases is SubDbContext. So you must enable migration based on one of them. then put this code as Configuration class:
internal sealed class Configuration : DbMigrationsConfiguration<SubDbContext>
{
public Configuration()
{
AutomaticMigrationsEnabled = true;
}
}
and put this code into the SubDbContext constructor:
Database.SetInitializer<SubDbContext>(new MigrateDatabaseToLatestVersion<SubDbContext, Configuration>());
it means, every database when found a new manual added Migration,
then try to migrate it.
and also you can use this approache too:
write this code in the Application_Start:
var context = new SubDbContext("your generated connection string");
var initializeMigrations = new MigrateDatabaseToLatestVersion<SubDbContext, Configuration>();
initializeMigrations.InitializeDatabase(context);
I hope you find it helpful.

How to specify Object type when I use a Stored Procedure?

I've a project where I'm using LINQ to SQL. Inside the SQL Server, I've defined a custom stored procedure called [MyObjectEnabled] which returns object following a where clause:
SELECT *
FROM MyObject
WHERE MyDate IS NOT NULL
But when I import the stored procedure into my DataContext, the type of the result object is MyObjectEnabledResult, not MyObject.
I need to go to the DataContext.cs and edit the returning type manually. But every time I'll import a stored procedure on this DataContext, the previous edits will be erased.
So: how can I tell SQL Server to get the returned type right? I hope the question is clear.
The classes LINQ to SQL creates are partial; so you can make separate code file like MyObjectEnabledResult.cs and in this code file have MyObjectEnabledResult inherit shared interface and then work just with the shared interface. The same you can do for the LINQ to SQL queries for MyObject.
// auto-generated by LINQ
public partial class MyObjectEnabledResult
{
public int ID { get; set; }
}
// auto-generated by LINQ
public partial class MyObject
{
public int ID { get; set; }
}
// your own code behind - ISharedInterface.cs
public interface ISharedInterface
{
int ID { get; set; }
}
// your own code behind - MyObjectEnabledResult.cs
public partial class MyObjectEnabledResult : ISharedInterface
{
}
// your own code behind - MyObject.cs
public partial class MyObject : ISharedInterface
{
}
// get the db context
var query1 = db.MyObjectEnabled().Cast<ISharedInterface>();
var query2 = from mo in db.MyObjects select (ISharedInterface)mo;

How come my ContextInitializer for EF 6 has zero refrences?

I'm trying to learn EF 6 Code-first in WPF by following some tutorials. Since I'm familiar with model-first I can understand most parts except I've found ContextInitializer a little confusing. I defined a ContextInitializer like this code:
public class ContextInitializer : DropCreateDatabaseIfModelChanges<Context>
{
protected override void Seed(Context context)
{
var customers = new List<Customer>
{
new Customer{Name="Jane",Phone="2238718"},
new Customer{Name="David",Phone="43245608"},
new Customer{Name="Mike",Phone="90814417"}
};
customers.ForEach(cu => context.Customers.Add(cu));
context.SaveChanges();
}
}
and this is my Context class:
public class Context : DbContext
{
public Context()
: base("MVVM")
{
}
public DbSet<Customer> Customers { get; set; }
}
and It created a database at first run which I think it's weird because this class has zero refrences. Since Seed method doesn't fire again, I can't understand how this works.
Can someone explain to me how my ContextInitializer with zero reference created a database?
Does the following section exist in your App.Config?
<contexts>
<context type="(your name space).Context, MVVM">
<databaseInitializer type="(your name space).ContextInitializer, MVVM" />
</context>
</contexts>
If it is, the program knows where to look to find the ContextInitializer. If the database already exists and the tables in the database already match those of the POCO/model classes, nothing happens. If the model has changed or the database doesn’t exist, this class will be invoked, resulting in the database being seeded with your data.

RIA Services SP2 Function Complex type not visible in Object Context

I am struggling with returning a complex type from my services layer. It doesnt seem to be accessible from my object context.
This is the query in the service layer. All compiling fine.
public IQueryable<USP_GetPostsByThreadID_Result> uspGetPostsByThreadID(int ThreadID)
{
return this.ObjectContext.USP_GetPostsByThreadID(ThreadID).AsQueryable();
}
When I try and call it from my client, the ForumContext is not seeing it. I checked the client generated file and nothing similar is being generated. Help!!!
The name of your method may not meet the expected convention for queries. Try one or both of the following:
Add the [Query] attribute
Rename the method to GetUspPostsByThreadID
Result:
[System.ServiceModel.DomainServices.Server.Query]
public IQueryable<USP_GetPostsByThreadID_Result> GetUspPostsByThreadID(int ThreadID)
{
return this.ObjectContext.USP_GetPostsByThreadID(ThreadID).AsQueryable();
}
Its very common to have a stored procedure returning data from multiple tables. The return type doesn't fit well under any of the Entity Types(Tables). Therefore if we define Complex Type as the return collection of objects from Stored Procedure invocation, it becomes quite a powerful tool for the developer.
Following these steps I have achieved successfully the configuration of complex type on a sample AdventureWorks database.
1. Refer the picture and ensure the Stored procedure and function import is done.
2. Add the Domain Service name it as AdventureDomainService.
3. Now its time to define the tell the RIA services framework to identify my Complex Type as Entity Type. To be able to do this, we need to identify a [Key] DataAnnotation. Entity types provide data structure to the application's data model and by design, each entity type is required to define a unique entity key. We can define key on one property or a set of properties in metadata class file AdventureDomainService.metadata.cs
First define the class then add MetadatatypeAttribute like :
[MetadataTypeAttribute(typeof(CTEmployeeManagers.CTEmployeeManagersMetadata))]
public partial class CTEmployeeManagers
{
internal sealed class CTEmployeeManagersMetadata
{
private CTEmployeeManagersMetadata() { }
[Key]
public int EmployeeID { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public int ManagerID { get; set; }
public string ManagerFirstName { get; set; }
public string ManagerLastName { get; set; }
}
}
Define the Domain service method to return the collection of objects/entities for populating the Silverlight Grid or any other data consuming controls.
public IQueryable<CTEmployeeManagers> GetEmployeeManagers(int empId)
{
return this.ObjectContext.GetEmployeeManagers(empId).AsQueryable();
}
We define IQueryable if we are to fetch the records from datasources like SQL, whereas we define IEnumerable if we are to fetch the records from in memory collections,dictionaty,arrays.lists, etc.
Compile the server side to generate the client proxy.
In the Silverlight side open the MainPage.xaml or wherever the datagrid is put, then add following namespaces :
using System.ServiceModel.DomainServices.Client;
using SLBusinessApplication.Web;
using SLBusinessApplication.Web.Services;
..
Load the data and display:
public partial class MyPage : Page
{
AdventureDomainContext ctx = new AdventureDomainContext();
public MyPage()
{
InitializeComponent();
LoadOperation loadOp = this.ctx.Load(this.ctx.GetEmployeeManagersQuery(29));
myGrid.ItemsSource = loadOp.Entities;
}
// Executes when the user navigates to this page.
protected override void OnNavigatedTo(NavigationEventArgs e)
{
}
}
That is all that is needed to do.
It has to be part of an entity. Complex types cannot be returned by themselves

MVC Model Confusion

I have confusion regarding models when we have relations between multiple tables. Formerly, I was using views or stored procedures of SQL to manipulate data but now I am using Entity Framework so confused how my model should look like ?
I have a table for Users, UserImages, UserRoles.
UserImages and UserRoles is referring to UserID from Users table.I am not sure how my model should be. While displaying data I generally use a view created in SQL server by joining these 2 tables. And when an user is edited or created I update these 3 tables.
Not sure what should my model look like in this case ? Do I create a SQL server view and add it to edmx ? Or add 3 tables separately in EDMX and create custom properties in User model for those other 2 tables?
[HttpPost]
public ActionResult Create(UserFormViewModel UserView)
{
User user = UserView.User;
try {
if (ModelState.IsValid) {
repository.AddUser(user);
repository.Save();
return View(new UserFormViewModel(user));
} else {
return View(new UserFormViewModel(user));
}
} catch (Exception ex) {
ModelState.AddModelError("Error", ex.Message);
return View(new UserFormViewModel(user));
}
}
public class UserFormViewModel {
UucsrRepository repository = new UucsrRepository();
public User User { get; private set; }
public SelectList States { get; private set; }
public SelectList Genders { get; private set; }
public SelectList RolesLists { get; private set; }
public SelectList SelectedRolesLists{ get; private set; }
public UserFormViewModel(User contact) {
User = contact;
States = new SelectList(repository.GetAllStates() ,"ShortName","Name");
Genders = new SelectList(repository.GetAllGenders(), "Gender", "Description");
RolesLists = new SelectList(repository.GetAllRolesLists(), "Id", "Name");
}
}
I am not sure how should I exactly handle the Adding role list and images here .
The User class should have a list of Roles and Images. The tables should have foreign keys to each other by UserId. When generating the models from your tables select all the tables you want Entity Framework to use. The User model should in that case automatically have a List of UserRoles and UserImages. Change the names appropriately.
When adding or changing roles or images you should fetch the user and update or add them to the correct list.
That's how I would do it. In this case your User is an aggregate root. Check out DDD you're interested.

Resources