Entity Framework Navigation Property Zero Results - asp.net-mvc

I have a simple relation between a User model and a Role model.
public class User {
{
public User() {
Roles = new HahSet<Role>();
}
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int Id { get; set; }
public virtual ICollection<Role> Roles { get; set; }
}
public class Role {
public Role()
{
Users = new HashSet<User>();
}
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int Id { get; set; }
public virtual ICollection<User> Users { get; set; }
}
On my development system, when querying user.Roles, I get the intended result of 3 Roles. When deployed to a test environment, the same query returns 0 Roles.
I have logged and monitored both environments. Both systems
Run the same code base and record the same logging statements
Execute the same SQL queries against an identical database (via both logging and SQL Profiler), so I can see it requesting the data from the database
Have the required database records
Are able to load User, but the test environment does not turn the Roles into objects on the user.Roles collection
Edit: Running the SQL queries manually on both development and testing databases return the expected results.
As far as I can, my environment and configs are identical.
My question is, what sort of environmental and/or configuration areas can I investigate to work out what is happening in the test environment?

To be on the safe side can you just verify the two objects.. They have to look something like this...
public class User {
{
public User() {
Roles = new HahSet<Role>();
}
[Key]
public int UserId { get; set; }
public virtual ICollection<Role> Roles { get; set; }
}
public class Role
{
[Key]
public int RoleId { get; set; }
[ForeignKey("User ")]
public int UserId { get; set; }
public User User { get; set; }
}

Related

Code first EF 6 auto generated relation table with additional column

I am trying to create new table with relation many to many in the code first.
I have got two tables: Users and Projects. Now, i want to have relation many to many for this two tables. So i do following:
public class Project
{
[Key]
[DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
public int Id { get; set; }
public string Name { get; set; }
public string Description { get; set; }
public string PositionCount { get; set; }
public bool IsActive { get; set; }
public virtual ICollection<User> Users { get; set; }
}
public class User : IdentityUser<Guid, UserLogin, UserRole, UserClaim>
{
public override Guid Id { get; set; }
public string Tags { get; set; }
public User()
{
Id = Guid.NewGuid();
}
public async Task<ClaimsIdentity> GenerateUserIdentityAsync(UserManager<User, Guid> manager)
{
// Note the authenticationType must match the one defined in CookieAuthenticationOptions.AuthenticationType
var userIdentity = await manager.CreateIdentityAsync(this, DefaultAuthenticationTypes.ApplicationCookie);
// Add custom user claims here
return userIdentity;
}
public virtual ICollection<Project> Projects { get; set; }
}
public class RecruitmentDbContext : IdentityDbContext<User, MyRole, Guid, UserLogin, UserRole, UserClaim>
{
public DbSet<Project> Projects { get; set; }
public DbSet<UserProject> UserProjects { get;set; }
public RecruitmentDbContext()
: base("RecruitmentDB")
{
}}
I saw on this page that this is enough to create new table with relation many to many. This is true, because everything works properly. But i want to add new column to this auto generated table, with name "ApplicationStatus". I need this column, because i need to know, if for current user, current project has current status :)
So summarizing:
I want to have got a table with relation many to many and with additional column named ApplicationStatus. Is it possible to get this on auto generated table, or maybe i should create it by hand somehow?
Yes, that is possible. This should help.
Entity Framework : Customized Join Table in a Many to Many Relationship

mvc4 get results in controller from joining tables (entity framework)

I am not sure how to get the results from joining the tables in controllers.
There're 3 tables 'Groups' 'Users' 'GroupUser' (bridge table).
public class Group
{
[Key]
public int GroupID { get; set; }
public string Group_Name { get; set; }
public ICollection<User> Users { get; set; }
}
public class User
{
[Key]
public int UserID { get; set; }
public string User_Name { get; set; }
public ICollection<Group> Groups { get; set; }
}
I also have this EFContext class
base.OnModelCreating(modelBuilder);
modelBuilder.Entity<Group>()
.HasMany(g => g.Users)
.WithMany(u => u.Groups)
.Map(m =>
{
m.MapLeftKey("UserID");
m.MapRightKey("GroupID");
m.ToTable("GroupUSer");
});
Do I also need to build a GroupUser class (to represent the GroupUser bridge table)?
Then how do I get the results when joining the 3 tables to get list of groups and users?
GroupViewModel model = new GroupViewModel
{
Groups = .... // this should be a linq statement that get results
that contains all groups and users
};
The equal sql statemen would be
select *
from Group g
join GroupUser gu on g.GroupID=gu.GroupID
join User u on u.UserID=gu.UserID
No, intermediate class is not needed.
The main point of an ORM (Object-Relational Mapper, which is what Entity Framework is) is to abstract away the database and let you work in a pure object-oriented way. Intermediate tables are definitely a database term and are not needed here.
The only reason I can think of that may lead you to create an intermediate class is when you need a "payload" (an extra meta-data) on the association. For example:
public class User
{
public int Id { get; set; }
public int Email { get; set; }
public virtual ICollection<Account> Accounts { get; set; }
}
public class Account
{
public int Id { get; set; }
public virtual ICollection<User> Users { get; set; }
}
Now, if you want the user-to-account association to define whether the association is of "Own the account" type (Administrator), you can do something like:
public class User
{
public int Id { get; set; }
public int Email { get; set; }
public virtual ICollection<AccountUserAssociation> Accounts { get; set; }
}
public class Account
{
public int Id { get; set; }
public virtual ICollection<AccountUserAssociation> Users { get; set; }
}
public class AccountUserAssociation
{
public virtual User User { get; set; }
public virtual Account Account { get; set; }
public AssociationType AssociationType { get; set; }
}
public enum AssociationType { Regular, Administrator }

Implementing Company, Division, Department User Access Control in MVC4 with EF

This is my first question on stackoverflow, so please be gentle. I am writing a customer portal to a warehouse application using MVC4, Entity Framework and SimpleMembership. The warehouse hosts contents for multiple companies. Each company has divisions and departments. The users will have varying access to the information for their company, divisions, and departments. I am looking for an elegant solution for access control. So far, my model looks like this:
public class UserProfile
{
UserProfile()
{
this.AccessControl = new HashSet<AccessControl>();
}
[Key]
[DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
public int UserId { get; set; }
public string UserName { get; set; }
public Nullable<int> CompanyId { get; set; }
public virtual ICollection<AccessControl> { get; set; }
public virtual Company Company { get; set; }
}
public class AccessControl
{
public int AccessControlId { get; set; }
public int UserId { get; set; }
public int CompanyId { get; set; }
public Nullable<int> DivisionId { get; set; }
public Nullable<int> DepartmentId { get; set; }
public Boolean ReadAccess { get; set; }
public Boolean WriteAccess { get; set; }
// other properties for access control
public virtual UserProfile UserProfile { get; set; }
public virtual Company Company { get; set; }
public virtual Division Division { get; set; }
public virtual Department Department { get; set; }
}
public class Content
{
public int ContentId { get; set; }
public int CompanyId { get; set; }
public int DivisionId { get; set; }
public int DepartmentId { get; set; }
// Various other properties
public virtual Company Company { get; set; }
public virtual Division Division { get; set; }
public virtual Department { get; set; }
}
My thought was that a NULL Division means all divisions and a NULL Department means all departments. My questions are:
What is an elegant way to write the repository method to retrieve a list of Content objects for a user based on their access control list as well as populating division and department select lists in CRUD views?
Is there a better way to model this access control list?
I don't think this addresses all of your questions yet, but I think a repository that looks something like this:
public class accessRepository
{
accessContext context = new accessContext();
public IQueryable<Content> GetAccessibleContentFor(int userId)
{
var up = context.UserProfiles.Single(u => u.UserId == userId);
var companyId = up.CompanyId;
return from c in context.Content
where c.CompanyId == companyId
&& (up.AccessControl.Any(
a=>
a.CompanyId == c.CompanyId &&
a.DivisionId == c.DivisionId &&
a.DepartmentId == c.DepartmentId)
|| up.AccessControl.Any(
a=>a.CompanyId == c.CompanyId &&
a.DivisionId == c.DivisionId &&
a.DepartmentId == null)
|| up.AccessControl.Any(
a=>
a.CompanyId == c.CompanyId &&
a.DivisionId == null)
select c;
}
}
would allow you get back the content that is accessible if:
The content belongs to the user's Company.
The user Can access content for the Company, Division, and Department
Or the user can access content for the Company and Division (all Departments)
Or the user can access content for the Company (all divisions) [ all departments, is assumed in this case.]
You should look into a policy- and attribute-based solution that's independent of your app where you can write authorization policies e.g.
a user can access content in the warehouse if the content.department==user.department && content.company==user.company.
XACML sounds like the perfect model. I wrote this demo where I do access control on purchase orders based on the purchaser, the amount, the location and the status of the PO. I don't need to change the app code because I use XACML externally.

get Membership user object from another model

i want something like this :
public class Order
{
public Guid OrderID { get; set; }
public Guid UserId { get; set; }
public DateTime OrderDate { get; set; }
public decimal Amount { get; set; }
public virtual ICollection<OrderDetail> orderDetailByOrderID { get; set; }
public virtual MembershipUser userByOrderID { get; }
}
so from above code i want membership user to be access from Order object ....
however i tried it but its not working.
so please suggest some solution if you have come across this type situation
It sounds like you might be using Entity Framework Code First. If this is the case you'd probably want:
public virtual aspnet_Membership userByOrderID { get; set; }
instead of
public virtual MembershipUser userByOrderID { get; }
That would grab the aspnet_Membership entity that is tied to the UserId foreign key. The aspnet_Membership class is not quite the same as the MembershipUser entity, but they have many of the same properties.
If that won't work, you can always use your Order model as is, and generate a ViewModel that has the MembershipUser object.
public class OrderViewModel
{
public Order Order { get; set; }
public MembershipUser User { get; set; }
}
and create the ViewModel like this before passing it into a view
Order order = EntityDataContext.Orders.First();
var model = new OrderViewModel { Order = order, User = Membership.GetUser(order.UserId) }

Using VB.NET MVC3 and the Entity Framework "Code-First" method, how can I easily define multiple one-to-many relationships with the same model?

I'm very new to ASP.NET and could use some help.
For this scenario, I have 2 classes. One is a "project" class and the other is a "company" class. Essentially, what I need is one single "company directory" of all the companies we have relationships with, but I need to be able to freely slot them into 3 different slots within a project. It is possible that the same company could occupy all 3 slots, but it's equally likely that a different company will be placed in each slot.
Here are my classes:
public class Project
{
public int ID { get; set; }
public string Name { get; set; }
public int ClientID { get; set; }
public int PublisherID { get; set; }
public int DeveloperID { get; set; }
public Company Client { get; set; }
public Company Publisher { get; set; }
public Company Developer { get; set; }
}
public class Company
{
public int ID { get; set; }
public string Name { get; set; }
}
When I have used this basic outline in the past, the complex types I specify in the bottom half of the model definition will be auto generated based on the matching int ID properties specified earlier. For example, If I had a complex type "User" that was drawing it's data from a user table in my database, specifying (int UserID) within my class followed by (User User), the UserID field would be the actual field in my project table and the User object I specify will automatically be an object containing all the User information from the user table.
Using this method as I did in the classes specified above, however, does not work in the way I expected and instead creates not only ClientID, PublisherID, and DeveloperID but also creates CompanyID, CompanyID1, and CompanyID2 which are the fields that will actually be used when attempting to instantiate the Company objects I specified (even though those fields will contain null always).
Is there any way around this?
You just need to specify that your int properties are the foreign keys to your navigation properties.
public class Project
{
public int ID { get; set; }
public string Name { get; set; }
public int ClientID { get; set; }
public int PublisherID { get; set; }
public int DeveloperID { get; set; }
[ForeignKey("ClientID")]
public Company Client { get; set; }
[ForeignKey("PublisherID")]
public Company Publisher { get; set; }
[ForeignKey("DeveloperID")]
public Company Developer { get; set; }
}

Resources