Entity Framework Core error on Insert when exists a foreign key to a View - entity-framework-core

This is my model (semplified):
PRAT is the main table
public partial class PRAT
{
public int ID { get; set; }
public string PRATICA { get; set; }
public int ANNO { get; set; }
public string VARIANTE { get; set; }
[ForeignKey("ID")]
public VW_PRATICHE_CONTIPO VW_PRATICHE_CONTIPO { get; set; }
}
VW_PRATICHE_CONTIPO is a View (not a table!) in the database that contains some data related to PRAT table
public class VW_PRATICHE_CONTIPO
{
public int ID { get; set; }
public DateTime? DATAPRES { get; set; }
public string PROTGEN { get; set; }
public string TIPO { get; set; }
public string TIPOEXTRA { get; set; }
public string TIPOISTANZA { get; set; }
public string TIPOPRAT { get; set; }
}
The one-to-one relation between the table and the View is based on the ID field.
I need this because I want to do a query like this:
context.PRAT.Include(x=> x.VW_PRATICHE_CONTIPO)
This query works as exptected.
The problem happens when I try to save a new entity in PRAT.
When i do this:
context.PRAT.Add(prat);
await context.SaveChangesAsync();
I got this error:
The property 'ID' on entity type 'PRAT' has a temporary value. Either set a permanent value explicitly or ensure that the database is configured to generate values for this property.
If I remove the navigation property from PRAT all works fine, but I can't do the Include in my Query.
Can anybody help me?
Thank you.

Related

PostgreSQL Entity Framework Code First Migration generating new table for object type JSONB field

I am using .net core 3.1
public class Person
{
public int Id { get; set; }
[Required]
[MaxLength(50)]
public string FirstName { get; set; }
[Required]
[MaxLength(50)]
public string LastName { get; set; }
[Required]
public DateTime DateOfBirth { get; set; }
**[Column(TypeName = "jsonb")]**
public IList<Address> Addresses { get; set; }
}
public class Address
{
public string Type { get; set; }
public string Company { get; set; }
public string Number { get; set; }
public string Street { get; set; }
public string City { get; set; }
}
But, when I ran add migration command that generating new table for Addresses, that I don't want
I just want to capture address list in jsonb format but not in separate table.
I am using fluent api for configuration (just for understanding above class is decorated), do we have any property where I can specify to not generate new table for any object type property.
I tried - [NotMapped] but this ignore that specific column entirely
Thank you!

LINQ query throw exception on FirstOrDefault method

I'm using EF core, and I have a many-to-many relationship between two entity
IotaProject <--> User
Here's entities & dto related to the question
public class IotaProject
{
[Key]
public int Id { get; set; }
[Required]
public string ProjectName { get; set; }
[Required]
public DateTime Create { get; set; }
public ICollection<ProjectOwnerJoint> Owners { get; set; } = new List<ProjectOwnerJoint>();
}
public class ProjectOwnerJoint
{
public int IotaProjectId { get; set; }
public IotaProject IotaProject { get; set; }
public int UserId { get; set; }
public User User { get; set; }
}
public class User
{
[Key]
public int Id { get; set; }
[Required]
public string FullName { get; set; }
[Required]
public string ShortName { get; set; }
[Required]
public string Email { get; set; }
public ICollection<ProjectOwnerJoint> OwnedProjects { get; set; } = new List<ProjectOwnerJoint>();
}
public class ApplicationDbContext : DbContext
{
public DbSet<IotaProject> IotaProjects { get; set; }
public DbSet<User> Users { get; set; }
public DbSet<ProjectOwnerJoint> ProjectOwnerJoint { get; set; }
}
public class IotaProjectDisplayDto
{
public int Id { get; set; }
public string ProjectName { get; set; }
public DateTime Create { get; set; }
public UserMinDto Owner { get; set; }
public int Count { get; set; }
public IEnumerable<UserMinDto> Reviewers { get; set; }
}
public class UserMinDto
{
public int Id { get; set; }
public string FullName { get; set; }
public string ShortName { get; set; }
}
Following LINQ is the problem, the LINQ purpose is to convert IotaProject to IotaProjectDisplayDto, and key part is that Owners property of IotaProject is ICollection and Owner property in IotaProjectDisplayDto is just one single element UserMinDto, so I only need to get the first element of IotaProject's Owners and that's FirstOrDefault() comes.
IEnumerable<IotaProjectDisplayDto> results = _db.IotaProjects.Select(x => new IotaProjectDisplayDto
{
Id = x.Id,
ProjectName = x.ProjectName,
Create = x.Create,
Owner = x.Owners.Select(y => y.User).Select(z => new UserMinDto { Id = z.Id, FullName = z.FullName, ShortName = z.ShortName }).FirstOrDefault()
});
return results;
it throws run-time exception
Expression of type 'System.Collections.Generic.List`1[ToolHub.Shared.iota.UserMinDto]' cannot be used for parameter
of type 'System.Linq.IQueryable`1[ToolHub.Shared.iota.UserMinDto]'
of method 'ToolHub.Shared.iota.UserMinDto FirstOrDefault[UserMinDto](System.Linq.IQueryable`1[ToolHub.Shared.iota.UserMinDto])' (Parameter 'arg0')
I'm guessing it's probably related to deferred execution, but after read some posts, I still can't resolve it.
Any tips would be appreciated.
Right now, the only way I can get this work is I change type of Owner property in IotaProjectDisplayDto into IEnumrable, which will no longer need FirstOrDefault() to immediate execution. And later on, I manually get the first element in the client to display.
This issue happened in Microsoft.EntityFrameworkCore.SqlServer 3.0.0-preview7.19362.6
I end up downgrade to EF core stable 2.2.6 as Ivan suggested in comment, and everything works fine.

Entity Framework attempting to select non-existing column

I'm using Entity Framework 6.0 and have defined 2 POCO's to map to my database:
[Table("PortfolioGroups")]
public class PortfolioGroup : AuditableEntity<int>
{
[Column("Company_Id")]
public int CompanyId { get; set; }
[ForeignKey("CompanyId")]
public Company Company { get; set; }
public string Name { get; set; }
public string Description { get; set; }
public ICollection<PortfolioGroupItem> PortfolioGroupItems { get; set; }
public PortfolioGroup()
{
PortfolioGroupItems = new Collection<PortfolioGroupItem>();
}
}
And the PortfolioGroupItem:
[Table("PortfolioGroupItems")]
public class PortfolioGroupItem : AuditableEntity<int>
{
[Column("PortfolioGroup_Id")]
public int PortfolioGroupId { get; set; }
[ForeignKey("PortfolioGroupId")]
public PortfolioGroup PortfolioGroup { get; set; }
[Column("Trademark_Id")]
public int? TrademarkId { get; set; }
[ForeignKey("TrademarkId")]
public Trademark.Trademark Trademark { get; set; }
[Column("TrademarkRegistration_Id")]
public int? TrademarkRegistrationId { get; set; }
[ForeignKey("TrademarkRegistrationId")]
public TrademarkRegistration TrademarkRegistration { get; set; }
[Column("Domain_Id")]
public int? DomainId { get; set; }
[ForeignKey("DomainId")]
public Domains.Domain Domain { get; set; }
}
However - when I attempt to query the PortfolioGroups, Entity Framework for some reason attempts to query a field named "Trademark_Id" - which doesn't exist on the PortfolioGroup entity:
Context.PortfolioGroups.SingleOrDefault(i => i.Id == id && i.CompanyId == companyId);
Throws:
Invalid column name 'Trademark_Id'.
I've used this kind of setup other places in my application without any problems. I simply cannot find out why EF is trying to query a column that's not in my entity!
Any suggestions would be greatly appreciated. I'm at the end of my rope here.
Thanks guys! :)
The problem is that you've added a Navigation Property on Trademark that requires a Foreign Key on Portfolio Group:
public class Trademark
{
[Key]
public int Id { get; set; }
[MaxLength(250)]
[Required]
public string Name { get; set; }
[MaxLength(150)]
public string Filename { get; set; }
public ICollection<PortfolioGroup> PortfolioGroups { get; set; }
public Trademark()
{
PortfolioGroups = new Collection<PortfolioGroup>();
}
}
EF expects PortfolioGorup to have a Trademark_ID column to store which PortfolioGroups are associated with a Trademark.

System.InvalidOperationException: The property 'Emp_Status' is part of the object's key information and cannot be modified

I have the following code:
Class
public partial class Emp_Details
{
public long Emp_ID { get; set; }
public string Emp_Title { get; set; }
public string Emp_Name { get; set; }
public string Emp_LastName { get; set; }
public string Emp_Status{ get; set; }
}
entity Code
using (LoginEntities dbcontext = new LoginEntities())
{
Emp_Details emp = dbcontext.Emp_Details.Single(i => i.Emp_ID == empid);
emp.Emp_Status = status;
dbcontext.SaveChanges();
}
I am getting the exception
System.InvalidOperationException: The property 'Emp_Status' is part of the object's key information and cannot be modified.
I have searched for a solution and found 2 possible fixes:
1)Set a primary Key. If there is no primary key on a table, it will simply select the non-nullable columns as a concatenated primary key and the entity will be read/only.
2) Use a direct update such as:
dbcontext.Database.ExecuteSqlCommand(
"UPDATE Emp_Details SET [Emp_Status] = {0} WHERE [Emp_ID] = {1}", status, empid);
Is there any way to do this update without having to touch the database, set primary keys, or mess with the class file?
Your entity doesn't have a primary key. So:
public partial class Emp_Details {
public long Id { get; set; } // pay attention to this
public string Emp_Title { get; set; }
public string Emp_Name { get; set; }
public string Emp_LastName { get; set; }
public string Emp_Status{ get; set; }
}
Or
public partial class Emp_Details {
public long Emp_DetailsId { get; set; } // pay attention to this
public string Emp_Title { get; set; }
public string Emp_Name { get; set; }
public string Emp_LastName { get; set; }
public string Emp_Status{ get; set; }
}
Or
public partial class Emp_Details {
[Key] // pay attention to this
public long Emp_ID { get; set; }
public string Emp_Title { get; set; }
public string Emp_Name { get; set; }
public string Emp_LastName { get; set; }
public string Emp_Status{ get; set; }
}
Each of above changes, will solve the problem.

Multiplicity issue while mapping a table in Entity Framework

I currently have a class:
[Table("TitleCategoryMovie", Schema = "dbo")]
public class TitleCategoryMovie
{
[Key]
public int Id { get; set; }
public string CreatedBy { get; set; }
public DateTime CreateDatetime { get; set; }
public string UpdatedBy { get; set; }
public DateTime UpdateDatetime { get; set; }
[ForeignKey("Id")]
public virtual Title Title { get; set; }
}
There is a table called Title. And every TitleCategoryMovie has a corresponding Title, although not every Title has a TitleCategoryMovie. The column Id for Title is also the same for TitleCategoryMovie. But when I add both entity classes to my DbContext, it gives me an error:
Multiplicity is not valid in Role 'TitleCategoryMovieStandalone_Title_Source' in relationship 'TitleCategoryMovieStandalone_Title'. Because the Dependent Role refers to the key properties, the upper bound of the multiplicity of the Dependent Role must be �1�.
I've already defined my column Id in TitleCategoryMovie as a primary key and a foreign key to Title, so I don't know why it's giving me this error. What's wrong?
You should also add a TitleId field and use that one as the parameter in the [ForeignKey] attribute:
[Table("TitleCategoryMovie", Schema = "dbo")]
public class TitleCategoryMovie
{
[Key]
public int Id { get; set; }
public string CreatedBy { get; set; }
public DateTime CreateDatetime { get; set; }
public string UpdatedBy { get; set; }
public DateTime UpdateDatetime { get; set; }
public int TitleId { get; set; }
[ForeignKey("TitleId")]
public virtual Title Title { get; set; }
}
Update after comments
I believe something like this should work:
[Table("TitleCategoryMovie", Schema = "dbo")]
public class TitleCategoryMovie
{
[Key]
public int Id { get; set; }
public string CreatedBy { get; set; }
public DateTime CreateDatetime { get; set; }
public string UpdatedBy { get; set; }
public DateTime UpdateDatetime { get; set; }
public virtual Title Title { get; set; }
}
[Table("Title", Schema = "dbo")]
public class Title
{
[Key]
[ForeignKey("TitleCategoryMovie")]
public int Id { get; set; }
public string Something { get; set; }
public virtual TitleCategoryMovie TitleCategoryMovie { get; set; }
}
You should put the [ForeignKey] attribute in the class that you consider to be the child of the relationship.
I was mapping two entities to one table. Apparently this isn't allowed in Entity Framework, so that was why I was getting that error.