No key defined. Define the key for this EntityType when implementing interface that has Id - ef-code-first

I want to implement an interface defined in Dev Express IResource in my EF Code First business object.
public class JResource : IResource , IXafEntityObject
{
[Key]
public int IdKey { get; set; }
[NotMapped]
public object Id => IdKey; // since IResource wants this.
// other properties
}
When I run my application to create the database I get an error that I need to define the key for this EntityType.
I think the problem is that EF wants to regard Id as the Key but I have made Id NotMapped since I want it to be an Int and the interface wants it to be an object.
Is there a work around?

It turned out that I was using the wrong reference for the [Key] attribute.
The correct one is
System.ComponentModel.DataAnnotations.KeyAttribute

Related

Ardalis CleanArchitecture - BaseEntity & Composite Keys for AggregateRoots

What is the recommendation for extending BaseEntity as an AggregateRoot is I need to have a composite Key?
Essentially I need to be able to manage an Entity that would normally be configured in EFCore like:
builder.HasKey(z => new { z.PartA, z.PartB });
Currently the template gives us the following definition of BaseEntity, but it's unclear to me how I might need to setup the EntityTypeCuilder config, and how the Aggregates might handle this scenario under the hood.
// This can be modified to BaseEntity<TId> to support multiple key types (e.g. Guid)
public abstract class BaseEntity
{
public int Id { get; set; }
public List<BaseDomainEvent> Events = new List<BaseDomainEvent>();
}
Paul

Including Identity User with Entity Framework doesn't work

I am having trouble including my Identity User in query results. Other entities are included just fine, no matter how many levels deep.
Here's the model I'm using.
Building * --- 1 City
* *
| /
| /
1 1
ApplicationUser
And the context:
public class ApplicationDbContext : IdentityDbContext<ApplicationUser>
{
public DbSet<City> Cities { get; set; }
public DbSet<Building> Buildings { get; set; }
}
Both Building and City have these properties:
public Guid ApplicationUserId { get; set; }
public virtual ApplicationUser ApplicationUser { get; set; }
The query I'm using to retrieve data:
var building = context.Buildings
.Include(c => c.ApplicationUser)
.Include(c => c.City)
.Include(c => c.City.ApplicationUser)
.First();
In the result City is populated just fine, however ApplicationUser is not.
Could this be a naming issue? I've already tried UserId / User and AspNetUserId / AspNetUser as property names without succes.
I'm using Migrations to create the database. The table name that gets created for users is AspNetUsers.
I'm using entity framework 7 beta 7, not sure if this applies to other versions as well.
These are the files generated by EF Migrations.
ApplicationDbContextModelSnapshot.cs
20150929181902_Init.cs
20150929181902_Init.Designer.cs
(I noticed I forgot to include the Building > City relation when generating files for upload, but that shouldn't matter for the example)
I've finally figured it out.
ApplicationUser inherits from IdentityUser which inherits from IdentityUser<string>. The generic type is used as the primary key, so a string!
I changed my Guid foreign key properties to strings and now everything is working.
Just to help anyone who also have a similar issue. I was facing same thing, same scenario: My custom identity user has some related entities and using .Include was not working. None of them would come back. But they used to.
Turns out I had created a custom ApplicationUserStore to automatically include the entities I would normally always need when retrieving a User but I had only overridden FindByIdAsync method. When I tried to use FindByNameAsync no entity would come back, obviously. Just had to override this and the other Find methods.

Ignore column but populate property through stored procedure EF code first

I have ignored a column through fluent API but want to populate that property while executing stored procedure using some logic. But it is not mapping the ignored column property. Please let me know if there is any way to do this in Entity framework code first.
I've faced with the same problem recently. The only solution I found is a class hierarchy:
public class MyEntityBase {
public int Id { get; set; }
}
public class MyEntity: MyEntityBase {
...
}//This class is mapped to DB with a fluent API and does not contain ignored property.
//Also it does not have derivative classes, so EF will not create class inheritance in DB.
public class DerivedEntity: MyEntityBase {
public int IgnoredProperty { get; set; }
}//Use this class while executing stored procedures
P.S. Do not mark class MyEntityBase as ABSTRACT - EF will map this relationship as database inheritance.

How to delete child entities in an InverseProperty relationship using code first entity framework 4.1

I have a model and I am having trouble managing the relationships using entity framework 4.1
Here the model (simplified):
public class UserConfig {
[Key]
[Column("id", TypeName = "bigint")]
public long Id { get; set;}
[InverseProperty("UserConfigId")]
public virtual List<ColumnConfig> ColumnConfigs { get; set; }
}
public class ColumnConfig {
[Key]
[Column("id", TypeName = "bigint")]
public long Id { get; set; }
[Column("user_config_id", TypeName = "bigint")]
public long UserConfigId { get; set; }
[Column("width", TypeName = "int")]
public int Width{ get; set; }
[Column("col_name", TypeName = "varchar")]
public string ColumnName{ get; set; }
}
The model represents a user and a custom view of a table of data within a UI. They resize the columns the way they want and then save their settings. I have a webservice that accepts a list of the columns they want and their respective widths.
The problem I am having is updating the user's ColumnConfigs within my web service. The webservice does not receive the ColumnConfig id's, so my approach has been to try and first delete all the existing ColumnConfigs for the user, and then second create a new set of objects according to the new values passed in.
I can't manage to delete any of the ColumnConfig objects. Here's my code:
public void UpdateUserConfig(UserConfig uc) {
UserConfig origUserConf = ctx.ColumnConfigs.Find(new object[] {uc.Id});
origUserConf.ForEach(uc => ctx.ColumnConfigs.Remove(uc)); // remove old
origUserConf.ColumnConfigs = uc.ColumnConfigs; // add new
ctx.SaveChanges();
}
This isn't working, it gives the error:
System.InvalidOperationException: The operation failed: The relationship could not be changed because one or more of the foreign-key properties is non-nullable. When a change is made to a relationship, the related foreign-key property is set to a null value. If the foreign-key does not support null values, a new relationship must be defined, the foreign-key property must be assigned another non-null value, or the unrelated object must be deleted.
at System.Data.Objects.ObjectContext.SaveChanges(SaveOptions options)
at System.Data.Entity.Internal.InternalContext.SaveChanges()
at System.Data.Entity.Internal.LazyInternalContext.SaveChanges()
at System.Data.Entity.DbContext.SaveChanges()
I'm not sure why is thinks there is a null constraint here. I haven't specified any fields as being required.
The easiest way to remove child relationships would be to invoke:
origUserConfig.ColumnConfigs.Clear();
Unfortunately, this wouldn't work for you for two reasons: (1) You have a non-nullable relationship defined between your Parent and Child entity, and (2) even if the relationship was defined as nullable it would orphan the child rather than deleting it.
Read this article (Deleting Foreign Key Relationships in EF4) to get an idea of how EF handles deleting child entities. In your case you fall under case number 1.
As far as the error you're getting change your foreach to use the ForEach method off the List<T> class:
origUserConf.ColumnConfigs.ForEach(col => ctx.ColumnConfigs.Remove(col))

Wcf ria services - custom objects with EF entities - can't compile

I have custom entity (not from entity model), which have a property, wich return collection of EF entities (from entity model):
[DataContract]
public class MyEntity
{
[DataMember]
public List<Role> Roles { get; set; }
}
The 'Role' and 'RolePermission' entities are generated by EF4 from DB.
RolePermission has FOREGIN_KEY to Role, and EF4 was generated association between Role and RolePermission:
Role.RolePermissions --navigate property
RolePermission.Role --navigate property
Also, I have DomainService:
[EnableClientAccess()]
public class MyEntityService : DomainService
{
public List<MyEntity> GetMyEntities()
{
...
myEntityInstance.Roles = <GetRoles>
...
return <collection of MyEntities with Roles>
}
}
When I try to compile this, I get error:
Entity 'UserManager.Web.RolePermission' has a property 'RoleReference' with an unsupported type
When I put [Include] attribute to MyEntity.Roles property, I get the same error and this error:
Property 'Roles' of complex type 'MyEntity' is invalid. Complex types cannot have include members.
when I removed reference from RolePermission to Role (RolePermission.Role navigate property) by hands (from entity model), I get only this error in compile time:
The Entity 'Role' in DomainService 'RolesService' does not have a key defined. Entity types exposed by DomainService operations must have at least one public property marked with the KeyAttribute.
How can I resolve this situation? How can I return my custom object (MyEntity) with filled Roles property from MyEntityService?
A added [key] attr to Role.Metadata, and compile succesfull. But there are no MyEntity.Roles property on the client.
RIA services requires all objects passed back and forth between client to server to have a unique key so it knows which specific object you are modifying.
If you must have your own object as a wrapper for EF objects, just add an id member marked with [key] and maintain that value yourself.
[DataContract]
public class MyEntity
{
[key]
public int Id { get; set; }
[DataMember]
public List<Role> Roles { get; set; }
}
There seems to be something wrong with the design if you need to do that. What is the parent of a group of roles in your application? Why not just query roles?

Resources