"Invalid object dbo.RoleUsers" error using EF Database-first on insert - sql-server

I have a DB from which I have generated the models using Database-First through Entity Framework.
The picture below shows what's in the database:
When I do the following in my code (inserting a user with the associated role):
using (var context = new ApplicationDbContext())
{
var role = new Role {Name = "Admin"};
var user = new User {UserName = username,
PasswordHash = passwordHash,
Roles = new List<Role> { role }};
context.Set<User>().Add(user);
context.SaveChanges(); //Error here
}
It throws the following error:
An error occurred while saving entities that do not expose foreign key properties for their relationships. The EntityEntries property will return null because a single entity cannot be identified as the source of the exception. Handling of exceptions while saving can be made easier by exposing foreign key properties in your entity types. See the InnerException for details.
and in the InnerException I get:
Invalid object name dbo.RoleUsers
which is pretty strange since I have a table UserRoles, not RoleUsers.
Does anyone knows what the source of the error is here?
Thanks,
Ionut

Related

Using Always Encrypted with Entity Framework and Azure Key Vault

I've encrypted some columns in an Azure SQL Database, using Always Encrypted and a column master key stored in an Azure Key Vault, but I'm having trouble accessing them from my application using Entity Framework.
There's a recent MSDN article and an older blog post that explain how to set up a SqlConnection to use Always Encrypted with an Azure Key Vault, so I'm guessing that a normal DbContext could be created using the constructor that accepts a DbConnection.
The problem is that I'm using an IdentityDbContext, which doesn't have that constructor - the only constructor that takes a DbConnection also takes a DbCompiledModel, which is beyond my pay-grade at the moment.
Can anyone explain how to set up an IdentityDbContext to use the Key Vault?
It seems that EF team have a test that uses encryption.
var connectionStringBuilder = new SqlConnectionStringBuilder(SqlServerTestStore.CreateConnectionString("adventureworks"))
{
Encrypt = encryptionEnabled
};
var options = new DbContextOptionsBuilder();
options.UseSqlServer(connectionStringBuilder.ConnectionString);
using (var context = new AdventureWorksContext(options.Options))
{
context.Database.OpenConnection();
Assert.Equal(ConnectionState.Open, context.Database.GetDbConnection().State);
}
TODO: test IdentityDbContext Constructor exposes same constructor as AdventureWorksContext.

JPA One to Many Relation in Google App Engine

I have a one to many relationship (profile to message). I tried to save a message owned by a certain user/profile. What wrong with the code below?
public Message createMessage(Message msg, String recepient) {
EntityManager em = EMF.get().createEntityManager();
UserAccess access = new UserAccess();
Profile user = access.searchUser(recepient);
msg.setUser(user);
em.getTransaction().begin();
em.persist(msg);
em.getTransaction().commit();
em.close();
return msg;
}
search user method
public Profile searchUser(String displayName){
EntityManager em = EMF.get().createEntityManager();
Profile user;
try{
Query q = em.createNamedQuery("Profile.searchByDisplayName");
q.setParameter("displayName", displayName);
user = (Profile) q.getSingleResult();
} catch(javax.persistence.NoResultException e){
user = null;
}
em.close();
return user;
}
I encountered the error below:
java.lang.IllegalStateException: Primary key for object of type Profile is null.
Can it be because you do not have an "Id", a primary key, defined in your Profile Entity? Or is not set to any value when you created the specific profile?
Also, check if the relationships are defined properly between the Profile and Message entities.
jpa OneToMany & ManyToOne

How to detect which user clicked the link MVC3 membership

When user clicks the link this method takes the user id and other data and writes it to the database. I can't seem to find a way to track what is the user id since the id is automatically generated.
I am using membership base separately from my base. In order to find userID I was trying to compare UserName strings. I get this error: "An unhandled exception was generated during the execution of the current web request." Also "Cannot create an abstract class."
Is there a better way to compare two strings form the two databases? Or is there a better way? This is my first time using lambda expressions.
I tried using Single() and First() instead of Where(), but I still get the same error.
[HttpPost]
public ActionResult AddToList(Review review, int id, HttpContextBase context)
{
try
{
if (ModelState.IsValid)
{
//User user = new User();
//user.UserID = db.Users.Where(c => c.UserName == context.User.Identity.Name);
User user = new User();
Movie movie = db.Movies.Find(id);
review.MovieID = movie.MovieID;
string username = context.User.Identity.Name;
user = (User)db.Users.Where(p => p.UserName.Equals(username));
review.UserID = user.UserID;
db.Reviews.Add(review);
db.SaveChanges();
return RedirectToAction("Index");
};
}
catch (DataException)
{
//Log the error (add a variable name after DataException)
ModelState.AddModelError("", "Unable to save changes. Try again, and if the problem persists see your system administrator.");
}
return View(review);
}
you're problem is likely this line:
user = (User)db.Users.Where(p => p.UserName.Equals(username));
the Where() extension method returns an IEnumerable, not a single instance, so your implicit cast will fail every time. what you're looking for is either First() or FirstOrDefault(). First() will throw an exception if there is no match though, while FirstOrDefault()will return a null if no match is found. the line should be :
user = db.Users.First(p => p.UserName.Equals(username));
you probably have bigger problems than that, but this is the cause of your current error.
EDIT
upon further looking at your code, you're asking for a HttpContextBase in your action result call. you never use it, and it's probably the cause of the Cannot create an abstract class exception. remove that parameter and see if you get any different results.

How to ensure unique column value inside code?

I am learning ASP.NET MVC, and confused as to how can I ensure unique values for columns (username & email) for a table.
Can anybody help me with a sample code or a link to the tutorial which shows & explains this?
EDIT:
I know that I can apply an unique key constraint on my table columns and achieve it. However, I want to know how can I achieve it via ASP.NET MVC code?
UPDATE:
I wish to do a check in my application such that no duplicated values are passed to DAL, i.e. achieve a check before inserting a new row.
Mliya, this is something you are controlling at the database level, not at the application level.
If you are designing a database with a users table in which you would like to constraint the username and email columns to be UNIQUE you should create a UNIQUE INDEX on such columns.
without knowing your backend database (mySQL, SQL Server, MS Access, Oracle...) it's not the case to show you pictures or tell much more, just create the table with the designer and add these unique constraints to those columns and by design you will be sure no duplicated values will ever be inserted for username and email.
I also suggest you to create an ID column which would be set as PK (primary key, which means it will be automatically set as NON NULL and UNIQUE).
From your ASP.NET MVC application you should of course make sure that no duplicated values are then passed to the DAL for username and email. You could do this in different ways, the easiest is probably to check before inserting a new row if any user already exists with that username and/or email and if so you can show a notification message telling the user to please select another pair of values.
In an ASP.NET MVC architecture, you should try to do most of your validation in the Model, but with low-level validation rules like these, it's sometimes impossible. What you should look to for answers then is Domain-driven Design (DDD) where Application Services can solve such low-level needs.
Application Services will have access to the database (either directly, or better yet; indirectly through repositories) and can perform low-level validation and throw ValidationException or something similar (with detailed information the Controller can act upon and respond to the user) when a prerequisite or business rule isn't met.
S#arp Architecture implementes all of this in a best-practice framework that you can use as a basis for your ASP.NET MVC applications. It is highly opinionated towards DDD principles and NHibernate, and it will sometimes force your hand on how you do stuff, which is kind of the point. The most important part about it is that it learns you how to deal with these kinds of problems.
To answer your question more concretely and in the spirit of DDD, this is how I would solve it:
public class UserController
{
private readonly IUserService userService;
public UserController(IUserService userService)
{
// The IUserService will be injected into the controller with
// an "Inversion of Control" container like NInject, Castle Windsor
// or StructureMap:
this.userService = userService;
}
public ActionResult Save(UserFormModel userFormModel)
{
if (userFormModel.IsValid)
{
try
{
// Mapping can be performed by AutoMapper or some similar library
UserDto userDto = Mapper.Map<UserDto>(userFormModel);
this.userService.Save(userDto);
}
catch (ValidationException ve)
{
ViewBag.Error = ve.Detail;
}
}
// Show validation errors or redirect to a "user saved" page.
}
}
public class UserService : IUserService
{
private readonly IUserRepository userRepository;
public UserService(IUserRepository userRepository)
{
// The IUserRepository will be injected into the service with
// an "Inversion of Control" container like NInject, Castle Windsor
// or StructureMap:
this.userRepository = userReposityr;
}
public UserDto Save(UserDto userDto)
{
using (this.userRepository.BeginTransaction())
{
if (!this.userRepository.IsUnique(userDto.UserName))
{
// The UserNameNotUniqueValidationException will inherit from ValidationException
// and build a Detail object that contains information that can be presented to
// a user.
throw new UserNameNotUniqueValidationException(userDto.UserName);
}
userDto = this.userRepository.Save(userDto);
this.userRepository.CommitTransaction();
return userDto;
}
}
}

Setting only the ID in a Linq to SQL object

I am using Linq to SQL in a two tier project where the server tier abstracts the DB and is using Linq to SQL.
In my client tier I construct an object and I send to the server.
I have a Task, which has a relationship to Reporter (who reported this task), so Task has a ReportedID column in the database, which is a FK to Reporter.ID.
In the Linq abstraction, my Task has a Reporter property and a ReportedID property.
To save new Tasks, I would like to use the ReportedID, so I have this code:
//Populate the object with the info
Task task = new Task();
task.Title = tbTitle.Text;
task.Description = tbDescription.Text;
task.Severity = ((Severity)lbSeverities.SelectedItem);
//the first state: "open"
task.StateID = 1;
//TODO - Set ReporterID
task.ReporterID = 1;
//Save the task
client.SaveTaskCompleted += new EventHandler<SaveTaskCompletedEventArgs>(client_SaveTaskCompleted);
client.SaveTaskAsync(App.Token, task);
So, the object is constructed and sent to the server, where it is saved using this code:
public Task SaveTask(string token, Task task)
{
TrackingDataContext dataConext = new TrackingDataContext();
//Saves/Updates the task
dataConext.Tasks.InsertOnSubmit(task);
dataConext.SubmitChanges();
return task;
}
The problem is that I get an exception: "An attempt was made to remove a relationship between a Reporter and a Task. However, one of the relationship's foreign keys (Task.ReporterID) cannot be set to null.".
If I use the Reporter property, it works.
What am I doing wrong?
Thank you,
Oscar
I made some refactory in my code and this error doesn't anymore. It may be a logic error but I can't tell exactly what.

Resources