EF Core multiple realationship of a single column - c#

I am using EF Core 3.1 and I have five Models: Plant, Area, Unit, Schema, and EntitiesSchema.
In the EnititiesSchema, the EntityId may be a foreign key of Plant(PlantId), Area(AreaId), Unit(UnitId) tables.
How to handle this optional Relationship between these tables?
Thanks
public class EntitiesSchema
{
public int Id { get; set; }
public int EntityId { get; set; }
public int TopicId { get; set; }
public int SchemaId { get; set; }
public string Description { get; set; }
public Schema Schema { get; set; }
public ICollection<Topic> Topic { get; set; }
}

No, you can't relate a foreign key to multiple tables. But you can put another property named EntityType to store the type of entity. Then on the client-side, you can handle it. The EntityType can be an enum type.
Another approach is that storing "EntitesSchemaId" in the Plant, Area, Unit, etc models and relate them to the EntitiesSchema.

You can create an intermediary entity to map to different entity types. :
Public class EntityMap
{
public int Id {get;set;}
public string EntityKind {get;set;} // could be "Plant", "Area", "Unit", "Schema"
}
public class Plant
{
public int Id {get;set;}
public string EntityKind {get;set;} = "Plant";
}
public class EntitySchema
{
public int Id {get;set;}
public int EntityMapId {get;set;}
public EntityMap Map {get;set;}
}
The logic to read data from individual schema, has to be implemented in the client,but common properties of the entities can be added in EntityMap.
Here's a similar answer you might want to reference : https://stackoverflow.com/a/53649452/7491048

Related

EF one to many relationship using different columns instead of ID(primary key)

[Table("FirstClass")]
public class FirstClass {
public int ID { get; set; }
public int SpecialID { get; set; }
public virtual ICollection<SecondClass> SecondClassList { get; set; }
}
[Table("SecondClass")]
public class SecondClass {
public int ID { get; set; }
public int ParentSpecialID { get; set;}
public virtual FirstClass FirstClass { get; set; }
}
I want to map these classes with 'SpecialID' and 'ParentSpecialID'.
Is there an any way to do it?
I want to map these classes with 'SpecialID' and 'ParentSpecialID'. Is there an any way to do it?
Yes, but only in EF Core which supports Alternate Keys.
Well you can sort of do this in EF 6 too, if you declare SpecialID to be the Entity Key of FirstClass. Both ID and SpecialID must have unique indexes in the database, and so either one can be used as the Entity Key. But then all relationships refering to FirstClass must use SpecialID.

Would the Entity Framework's navigational properties work if I drop foreign key constraints from the database?

As you know that developers mostly mock the relationship between tables instead of using physical relationships between table (yeah, the line drawn from one table to another if you put a foreign key constraint on the column).
But I believe that Entity Framework doesn't work properly if physical relationships aren't there for navigational properties.
So, is there any way around?
My classes:
public class Phones
{
public int ID { get; set; }
public string Model { get; set; }
public string Manufacturer { get; set; }
public List<Users> Users { get; set; }
}
public class Sims
{
public int ID { get; set; }
public string Code { get; set; }
}
This creates a 1-M relationship from User -> Sims.
But what if I drop the foreign key constraint and leave it as it is, how will the navigational properties work then?
At this case better to remove references from both classes and handle relations manually outside of these classes:
public class Sims
{
public int ID { get; set; }
public string Code { get; set; }
//public User User { get; set; }
public int UserID { get; set; }
}

How to make proper code-first relations

I'm fairly new to Entity Framework and feel more in control using the Code-First pattern rather than DB-First.
I was wondering what is more preferred when it comes to programmatically setting up ForeignKey relations between the entities.
Is it better to declare a FK_ property in the class which relates to the another class or is it better to declare an IEnumerable<> property in the class that gets related to?
public class IRelateToAnotherClass
{
...
public int FK_IGetRelatedToByAnotherClass_ID { get; set; }
}
or
public class IGetRelatedToByAnotherClass
{
...
public IEnumerable<IRelateToAnotherClass> RelatedTo { get; set; }
}
It all depends on what type of relationships you want between your entities (one-to-one, one-to-many, many-to-many); but, yes, you should declare foreign key properties. Check out this site for some examples.
Here's a one-to-many for your two classes:
public class IRelateToAnotherClass
{
public int Id { get; set; } // primary key
public virtual ICollection<IGetRelatedToByAnotherClass> IGetRelatedToByAnotherClasses { get; set; }
}
public class IGetRelatedToByAnotherClass
{
public int Id { get; set; } // primary key
public int IRelateToAnotherClassId { get; set; } // foreign key
public virtual IRelateToAnotherClass IRelateToAnotherClass { get; set; }
}
and with some Fluent API mapping:
modelBuilder.Entity<IGetRelatedToByAnotherClass>.HasRequired<IRelateToAnotherClass>(p => p.IRelateToAnotherClass).WithMany(p => p.IGetRelatedToByAnotherClasses).HasForeignKey(p => p.Id);
If I understand what you're asking correctly, you'd want both. You want an int FK property and an object property to use as the navigation property.
The end result would look something like this:
public class Employee
{
[Key]
public int EmployeeID { get; set; }
[ForeignKey("Store")]
public int StoreNumber { get; set; }
// Navigation Properties
public virtual Store Store { get; set; }
}
public class Store
{
[Key]
public int StoreNumber { get; set; }
// Navigation Properties
public virtual List<Employee> Employees { get; set; }
}
If you haven't already, take a look at navigation properties and lazy-loading. Note that EF is clever enough to figure out that an int StoreID property corresponds to an object Store property, but if they are named differently (such as without the ID suffix), you must use the [ForeignKey] annotation.

EF Code first - Lazy Loading How to set up and access the joining table

public class Product
{
[Key]
public int Id { get; set; }
public string Name { get; set; }
public string Description { get; set; }
public decimal Price { get; set; }
public bool IsInStock { get; set; }
public string ImageUrl { get; set; }
public List<ProductOption> ProductOptions { get; set; }
public virtual Category Category { get; set; }
}
public class ProductOption
{
[Key]
public int Id { get; set; }
public string ProductOptionName { get; set; }
public string ProductOptionDescription { get; set; }
}
Now I know when your using Code First EF, so that the tables are created correctly. You need to do something like this.
modelBuilder.Entity<Product>().HasMany(p => p.ProductOptions).WithMany().Map(m =>
{
m.MapLeftKey("ProductId").MapRightKey("ProductOptionId").ToTable("SelectedProductOptionsInOrderedItem");
});
So....
Does this mean that if I do something like Product.ProductOptions I will be able to access all associated productoptions.
Is this the best way to set it up, or is there another way?
To enable lazy load and EF can create derived proxy types for your collection, that property should be declared this way:
public virtual ICollection<ProductOptions> ProductOptions { get; set; }
That should be enought. Other aspect is the mapping approach that you use. You choose fluent api, i prefer mapping by convention, but that is a matter of personal taste anyway.
Ok, Mapping by Conventions:
Is the ability of EF that from the name of entities and their properties along with their types, to map our model with the underlying data without providing any other information.
for example
public class Customer {
public long CustomerID {get; September;}
public string CustomerName {get; September;}
public Employee AssignedTo {get; September;}
}
With the previous model EF will map database with a table named Customer with:
. CustomerID bigint primary key column
. CustomerName nvarchar column
. Customer_EmployeeID foreign key to Employee table, with the datatype Corresponding to EmployeeID in that table.
You can read more Here

Entity Framework: Table that holds common data for different multiply entities

I have got a lot of tables in my DB and one that needs to hold common data for all of them. How can I map these tables using EntityFramework CodeFirst so I could Lazy or Eager load such data using normal queries?
Here is what I mean:
Entities:
public class Table1
{
[Key]
public int Id { get; set; }
...etc data
}
public class Table2
{
[Key]
public Guid Id { get; set; }
...etc data
}
public class Table3
{
[Key]
public string Id { get; set; }
...etc data
}
And a table with common data for all of them:
public class CommonDataTable
{
[Key]
public Guid Id { get; set; }
}
Normally I would map this by creating a table like:
public class CommonDataMappingTable
{
[Key]
public Guid Id { get; set; }
public string Mask { get; set; } // like: typeof(Table3).Name
public string MappedID { get; set; } // like: Table3.Id.ToString()
public virtual CommonDataTable MappedData { get; set; }
}
But as soon as I am new to Entity Framework I just do not know how to map such relation in EF CodeFirst model.
Thank you for your time and sorry for my bad English.

Categories