I am new to oData web services and I can not figure out how to remove certain unneeded columns from returning in my oData result. I tried to remove them from the model and that resulted in an error (problem in mapping fragments).
Let's just say my table is set up like this:
ID
Name
UpdateDate
CreateDate
I would prefer for my oData service to only return ID and Name, but entity framework wants to add all fields.
mark properties to be ignored with NotMapped attribute:
public class MyTable
{
public int ID { get; set; }
public string Name { get; set; }
[System.ComponentModel.DataAnnotations.Schema.NotMappedAttribute]
public DateTime UpdateDate { get; set; }
[System.ComponentModel.DataAnnotations.Schema.NotMappedAttribute]
public DateTime CreateDate { get; set; }
}
or ignore properties explicitly:
ODataConventionModelBuilder modelBuilder= new ODataConventionModelBuilder();
modelBuilder.EntityType<MyTable>().Ignore(_ => _.CreateDate);
modelBuilder.EntityType<MyTable>().Ignore(_ => _.UpdateDate);
Related
Specify a Parent-Child relationship in EF Core without using identity columns
What's an efficient way within Entity Framework Core 5 (C#) to work with the data in a hierarchial table that is linked via non-identity columns.
Here's my primary class:
public class ServiceProvider
{
[Key]
public int Id { get; set; }
public string ParentSPCode { get; set; }
public string SPCode { get; set; }
public string Name { get; set; }
public string City { get; set; }
public string State { get; set; }
public string ContactEmail { get; set; }
public string Status { get; set; }
}
The SPCode value is unique, which I enforce via C# code. The ParentSPCode may be null or must match an existing SPCode. Again I enforce this via C# code.
I want this table to hold any number of levels of parent-child (1 or more) records, as defined by ParentSPCode-SPCode pairs.
I can retrieve these records via a complex hierarchy of LINQ "joins", but I am thinking there must be a cleaner way by defining the appropriate EF Core 5 relationship.
If I was in SQL Server, I would do this via a CTE.
I want to be able to bring in the child records in a manner similar to .Include(q => q.ParentSPCode == x.SPCode).
Trying to create simple CRUD app using Asp Net Core. I have 2 entities:
Department and Employee( one to many ). I need to delete record from Department table. But when Im trying to delete record using OnDelete(DeleteBehavior.Restrict) or OnDelete(DeleteBehavior.ClientSetNull) i have exception:
UPDATE or DELETE in table"Departments" violates foreign key constraint
"FK_Employees_Departments_DepartmentCode" table"Employees"
How can i fix this problem ?
Entity Employee:
public class Employee
{
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int Id { get; set; }
[Required(ErrorMessage = "Input fullname of employee")]
public string FullName { get; set; }
[Required(ErrorMessage = "Input date of birth")]
public DateTime DateOfBirth { get; set; }
[Required(ErrorMessage = "Input code")]
public string Code { get; set; }
[Required(ErrorMessage = "Input fullname of employee")]
public int Salary { get; set; }
public string DepartmentCode { get; set; }
public Department Department { get; set; }
}
Entity Department:
public class Department
{
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int Id { get; set; }
[Required(ErrorMessage = "Input name of department")]
public string Name { get; set; }
[Required(ErrorMessage = "Input code of department")]
public string Code { get; set; }
public ICollection<Employee> Employees { get; set; }
public Department()
{
Employees = new List<Employee>();
}
}
Context class settings:
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Department>()
.HasMany<Employee>(d => d.Employees)
.WithOne(e => e.Department)
.HasForeignKey(e => e.DepartmentCode)
.OnDelete(DeleteBehavior.Restrict);
modelBuilder.Entity<Department>()
.HasKey(d => d.Code);
modelBuilder.Entity<Employee>()
.HasKey(e => e.Code);
modelBuilder.Entity<Department>()
.HasIndex(d => d.Name).IsUnique();
}
Of all fields in the DeleteBehavior enum only two actually add cascaded foreign key behavior to the database: Cascade and SetNull. All other options create foreign keys with no action on delete, but differ in what EF will do to its tracked entities.
In your case it should probably be SetNull because I assume that Employees can exist without Department. This setting will allow you to delete a Department object without loading its Employees. The database will set their DepartmentCode to null.
The delete behavior configured in EF can only be applied tho Entities that are tracked by EF change tracking. So you would need to load all Employees that belong to the department to make this work as expected.
BUT The database foreign key definition also defines the on delete action (cascading, set null, do nothing) So even if you code within your context a set null strategy, the DB still might apply different strategy for on delete. EF core defaults to cascade delete.
I've hit a snag while building a .net mvc site. I have 2 related objects and am struggling with properly linking them. Specifically:
public class Address
{
public int AddressId { get; set; }
public string Street { get; set; }
public string City { get; set; }
public string State { get; set; }
public string PostCode { get; set; }
[ForeignKey("AddressCategory")] // <-- EF adds field to below object's table
public int AddressCategoryId { get; set; }
public virtual AddressCategory AddressCategory { get; set; }
}
public class AddressCategory
{
public int AddressCategoryId { get; set; }
public string Description { get; set; }
}
Adding the [ForeignKey] data annotation to the Address object results in EF adding an Address_AddressId column to the AddressCategory table, which I don't want (or need) to happen.
I've tried to omit the ForeignKey attribute, but then I run into other errors because .net can't link the tables (e.g. Unknown column 'Extent1.AddressId' in 'field list'). Additionally, I wouldn't be able to use:
var addresses = db.Addresses.Include(l => l.AddressCategory);
Is there any way to link the 2 tables without EF adding an additional column to the AddressCategory table?
Thank you to #cloudikka for responding. After much trial-and-error I seem to have gotten it to work simply by omitting any ForeignKey reference from either object. I let EF rebuild the database and perform all scaffolding (CRUD forms) and they have been created perfectly.
My take-away is that foreign key attributes should be used for parent-child relationships, but not for look-up tables. I clearly have much to learn about asp.net mvc!
I have couple of entity who inherits base class with common fields like below:
[DataType(DataType.Text)]
[StringLength(100)]
public string CreatedBy { get; set; }
[DataType(DataType.DateTime)]
public DateTime? CreatedDate { get; set; }
[DataType(DataType.Text)]
[StringLength(100)]
public string ModifiedBy { get; set; }
[DataType(DataType.DateTime)]
public DateTime? ModifiedDate { get; set; }
I would like to fill these fields right before it goes to contex. Is there some events/method/handler which I may reuse to do some actions with entity before it placed to context?
I would like these fields are filled at the time its added to context, not put to the database.
Solution: Entity Framework/SQL2008 - How to Automatically Update LastModified fields for Entities?
Not sure 100% what you mean by filling these fields to context before they go to the database.. but if you want to persist them at some point these fields should be part of an object (entity) and then you can populate the poco using the setter method. You can always call context.Save()/Update() methods when you want to.
I read quite a number of posts of programmers that run into the Unable to determine a valid ordering for dependent operations. Dependencies may exist due to foreign key constraints, model requirements, or store-generated values -exception when using a self-referencing relationship in Entity Framework.
I am trying to get a parent-child relationship to work:
public class Category {
public int CategoryId { get; set; }
public string Name { get; set; }
public int ParentId { get; set; }
public Category Parent { get; set; }
public List<Category> Children { get; set; }
}
This is the configuration I use (Fluent API):
Property(c => c.ParentId).IsOptional();
HasMany(c => c.Children).WithOptional(c => c.Parent).HasForeignKey(c => c.ParentId);
//HasOptional(c => c.Parent).WithMany(c => c.Children).HasForeignKey(c => c.ParentId);
Both the HasMany() and HasOptional() configurations result in a "Unable to determine a valid ordering for dependent operations..." exception when I try to save a new category like this:
context.Categories.Add(new Category { Name = "test" });
I don't understand why EF doesn't insert the Category with a null parentId. The database allows the ParentId foreign key to be null.
Would you be able to tell me how to do this?
You must define the ParentId in the category class as nullable to use it as the foreign key property for an optional relationship:
public int? ParentId { get; set; }
An int property cannot take the value null and therefore cannot represent a NULL as value in a database column.
Since someone asked in a comment about doing this with attributes. You can also utilize data annotations to set this up. Using the same example as above:
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
public class Category {
// You can also add [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
// as an attribute, if this field is to be generated by the database
[Key] // Define this as the primary key for the table
public int CategoryId { get; set; }
public string Name { get; set; }
[ForeignKey(nameof(Parent))] // Link the Parent object to the ParentId Foreign Key
public int? ParentId { get; set; }
public Category Parent { get; set; }
public List<Category> Children { get; set; }
}
This is tested and works in EF 6.