MVC 4 Lookup UserName Based on UserId - asp.net-mvc-4

I'm using the MVC 4 template with VS 2012. I have enabled a comments section which stores the logged in user's UserId to a table. When I display the comments I want to display the user's user name and email from the UserProfiles table.
I've tried the following code:
public static string GetUserName(int userId)
{
using (var db = new UsersContext())
{
return db.UserProfiles.Single(x => x.UserId == userId).UserName;
}
}
But I get an exception:
The model backing the 'UsersContext' context has changed since the database was created. Consider using Code First Migrations to update the database (http://go.microsoft.com/fwlink/?LinkId=238269).
Any suggestions?

The exception is pretty descriptive. Your model does not reflect what your database look like. I recommend you to read this about code first migrations, basically what migrations mean is that you update your database to match your models, its done with one line of command in VS.
Hope this helps
Also I would recommend you to use .Find() or .First() instead of .Single()

Related

Saving user ID with Entity Framework

I'm using entity framework v6.2.0 and ASP Net MVC to create a web page to access a database and edit the entries. The overwhelming majority of the code is the basic framework provided for me. The database is connected successfully and entries can be viewed, edited, and deleted. Additionally I have implemented some rudimentary paging, searching, and sorting as instructions are provided by microsoft on how to implement those. The last thing I need to do before the site is truly functional is to pull the userID from the users login and save that as the EnteredBy field before saving any changes or new entries to the table.
if (ModelState.IsValid)
{
string currentUserId = User.Identity.GetUserId();
yasukosKitchen.EnteredBy = currentUserId;
db.YasukosKitchens.Add(yasukosKitchen);
db.SaveChanges();
return RedirectToAction("Index");
}
This code seems very simple, and I added using Microsoft.AspNet.Identity; so it compiles fine. However when I attempt to test this code the EnteredBy field is left blank or null.
My search for information turned up a post suggesting the use of the following line of code.
ApplicationUser currentUser = db.Users.FirstOrDefault(x => x.Id == currentUserId);
However when I attempt to add that I get an error, the ApplicationUser cannot be found and Users does not exist in this context. The fix for this is probably staring me in the face but my lack of experience and comprehension is killing me.
As suggested: My question is, how do I get and/or correctly add the UserId to my database entry?
If your Database Context has an entry to your YasukosKitchen table; usually something like this,
public virtual DbSet<YasukosKitchen> YasukosKitchens {get; set;}
and YasukosKitchen table has a column 'EnteredBy' (string 128 length), then you can post the value for the logged in user's Id straight from the View.
Add this to the very beginning of the Create view.
#using Microsoft.AspNet.Identity
#using Microsoft.AspNet.Identity.EntityFramework
At the end of the form just before the submit button, add this code.
#Html.HiddenFor(model => model.EnteredBy, new { #Value = User.Identity.GetUserId() })
I'm not sure what is the functionality of 'Users' table.

Entity Framework 6: Store update, insert, or delete statement affected an unexpected number of rows (0)

I am hoping someone can help me identify the cause of the following error when doing on update in Entity Framework.
Store update, insert, or delete statement affected an unexpected number of rows (0). Entities may have been modified or deleted since entities were loaded. Refresh ObjectStateManager entries.
From what I have read, it means that data has changed between the fetch and save, however this is not the case in my situation. (Single developer running the application locally. I also have viewed the data in the database before I attempt to save, and it is the exact same as when I did the fetch. Also able to reproduce this on command.)
I am not sure if this is relevant, but it seems to be the only factor that is different than other entities that are working. I have an entity that represents a table with a composite key. The value that I am updating is one of the values that makes up the composite key. There is only one record in the table at the moment, so I know there is no primary key violation stuff going on.
Does anyone know what steps I can take to find out what the actual problem is?
Thanks
If you have instead of trigger on table you are inserting to, it causes this error. You have to rewrite trigger to after insert trigger, or at the end of trigger select new generated id. Maybe for update there is similar problem. Look at query entity framework generates - it can help you to see what's going on.
EDIT:
To see generated queries set logging:
public class CustomContext : DbContext
{
public CustomContext()
: base("name=CustomString")
{
// configure writing queries to console
Database.Log = Console.Write;
}
// other context stuf ...
}
Or use some profiler (for sql server express you can use http://expressprofiler.codeplex.com/).
The problem resides in the fact that you call the method _dataContext.SaveChanges();, but nothing changed in the data. To avoid this error try this:
public void EditCustomer(Customer customer)
{
_dataContext.Customer.Attach(customer);
var entry = _dataContext.Entry(customer);
if(entry.Property(e => e.DeviceId).CurrentValue != entry.Property(e => e.DeviceId).OriginalValue)
{
entry.Property(e => e.DeviceId).IsModified = true;
}
if(entry.Property(e => e.Name).CurrentValue != entry.Property(e => e.Name).OriginalValue)
{
entry.Property(e => e.Name).IsModified = true;
}
if(entry.Property(e => e.DeviceId).IsModified || entry.Property(e => e.Name).IsModified)
{
_dataContext.SaveChanges();
}
}
I hope this helps you.
#DonPablone
I've encountered with such error message, my environment is as follows, SQL server 2016 along with ef6 database first and the issue was that the database developer did not define an identity seed column in the Id column of the table I'm inserting data into, and of course the issue solved when I updated the table design, so I'm sharing this experience in case if anyone got the same issue.
If by any chance, we have the same problem when trying to update record using Attach() and then SaveChanges() combination? This may help...
I am using SQLite DB and its EF provider (the same code works in SQLServer DB without problem).
I found out, when your DB column has GUID (or UniqueIdentity) in SQLite and your model is nvarchar, SQLIte EF treats it as Binary(i.e., byte[]) by default. So when SQLite EF provider tries to convert GUID into the model (string in my case) it will fail as it will convert to byte[]. The fix is to tell the SQLite EF to treat GUID as TEXT (and therefore conversion is into strings, not byte[]) by defining "BinaryGUID=false;" in the connectionstring (or metadata, if you're using database first) like so:
<connectionStrings>
<add name="Entities" connectionString="metadata=res://savetyping...=System.Data.SQLite.EF6;provider connection string="data source=C:\...\db.sqlite3;Version=3;BinaryGUID=false;App=EntityFramework"" providerName="System.Data.EntityClient" />
</connectionStrings>
Link to the solution that worked for me:
How does the SQLite Entity Framework 6 provider handle Guids?

ASP.NET MVC 4 Deferred query execution not retrieving data from database

I am new in ASP.NET MVC 4. In my project I am using Code First technique in of EF. I want to retrieve some data from database and I used following code for this :
List<SelectListItem> ls = new List<SelectListItem>();
var lm = from m in db.BOs //fetch data from database
select m;
foreach (var temp in lm)
{
ls.Add(new SelectListItem() { Text = temp.Name, Value = temp.Id.ToString() });
}
But when execution pointer move inside foreach it immediately come back out of the loop showing return ls value Count = 0. Code does not giving me any error while running that's why I am not getting where is going wrong.
UPDATE: I found something new this problem. When I kept mouse pointer over var lm; it shows me query and in query table name in FROM clause is not that one in my SQL database. My SQL table name is BO and in query it is taking BOes. I don't know from where this name is coming. So How I overcome this??
decorate your BO class with Table("BO") to specify the table name (attribute is in System.ComponentModel.DataAnnotations.Schema namespace)
[Table("BO")]
public partial class BO
{
...
Write following code inside DbContext class :
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
}
The modelBuilder.Conventions.Remove statement in the OnModelCreating method prevents table names from being pluralized. If you didn't do this, the generated tables would be named Students, Courses, and Enrollments. Instead, the table names will be Student, Course, and Enrollment. Developers disagree about whether table names should be pluralized or not. This tutorial uses the singular form, but the important point is that you can select whichever form you prefer by including or omitting this line of code.

Why does NHibernate need to know the ID of an auto ID based entity before flush is called?

With my only ORM knowledge being L2S/EF, I was surprised when the following code inserted a row into the database before I called repo.Save:
var repo = new UserRepository();
var user = new User { Name = "test" }
repo.Add(user);
//repo.Save();
Repo looks like this:
public void Add(T entity)
{
session.Save(entity);
}
public void Save()
{
session.Flush();
}
After some digging, it seems NHibernate needs to make the insert happen right away in order to get the ID of the new entity (since it's using an auto increment ID). But L2S/EF doesn't work like this; I can add many entities and save them all at the end.
Question is: is there a way to achieve the same thing with NHibernate, while still using auto increment IDs, and out of interest does anyone know why it works like this?
Fabio Maulo already blogged about the usage of identity generator a few times. The answer is: use hilo, guid.comb or something like this.
NHibernate needs the identity because every entity in the session (they are called "persistent entities") needs to be identified. The identity is also normally used to determine if the record already exists in the database (unsaved value).
session.Save actually only makes a transient entity persistent. When the database is generating the id, it needs to be stored to get the id. If NH can create the id itself (eg using hilo), it could be stored next time when the session gets flushed.

Unit testing NHibernate application with SQLite: it writes to the database but cannot read back

I have an application using NHibernate that is already deployed and working properly, and I'm re-factoring the unit tests to use SQLite for improved performance, and to keep unit test data out of the "real" database.
I have a simple test that creates an Calendar entity, saves it, then tries to read it back and verifies that it's the same object. The write works, but the subsequent select to read it back returns 0 records. A Calendar has a GUID as a primary key, and I understand that requires an extra parameter on the SQLite connection string. This is my connection string:
data source=:memory:;Version=3;New=true;Pooling=true;Max Pool Size=1;BinaryGuid=False
Through the logged SQL statements coming from NHibernate, I see the inserts to write the entity and its dependencies, then the subsequent select statement. It all looks good, but nothing is selected. If I use a file database instead of an in-memory database, I can open up the table in Visual Studio's Server Explorer, and I see the correct data in the tables. If I write a query to try selecting the record, like so:
SELECT CalendarID, Name, Description
FROM dbo_Calendars
WHERE (CalendarID = 'a9cd9820-1694-4645-88d4-f682c5a6b9cc')
it also fails to select anything. I think it's an issue with GUID handling, but I'm flummoxed.
Update
Here's what the test case looks like:
[Test]
public void SaveAndLoadCalendar()
{
Guid calId;
DAOFactory factory = (DAOFactory)DAOFactory;
ISession s = factory.SessionManager.CurrentSession;
using (var tx = s.BeginTransaction())
{
Calendar cal = new Calendar("Test Calendar", CalendarType.Test);
cal.Active = true;
cal.Browsable = true;
s.Save(cal);
tx.Commit();
calId = cal.ID;
}
Logger.InfoFormat("Calendar ID is {0} ", calId);
s.Clear();
using (var tx2 = s.BeginTransaction())
{
Calendar cal = s.Get<Calendar>(calId);
Assert.IsNotNull(cal, "Could not retrieve saved calendar");
Assert.AreEqual("Test Calendar", cal.Name, "Saved calendar not equal to original calendar");
}
}
I would guess that the transaction handling could be the problem.
So maybe the transaction inserting the record is not yet committed and so the (different) transaction performing the select does not yet see the new data - so the select returns nothing.
I figured it out, and the problem isn't NHibernate or SQLite, it's me. Each Calendar has an associated Theme. In our production database, these are manually entered, and expected to exist in advance. Now that I'm using SQLite for testing, I'm starting with an empty database, and this reference data isn't pre-populated. NHibernate's Select statement to fetch the Calendar uses an inner join on the Themes table, and with nothing in that table, the select will return empty. D'oh.
After updating my test setup code to save the default theme, the test passes.