Relationship with string field EF Core 7.0 - c#

how are you?
I have a need to relate 2 tables one to many with a string field that are not table keys
public class Schedule
{
public int Id { get; set}
public string Comment { get; set;}
public string Name { get; set;}
}
public class Products
{
public int Id { get; set;}
public string Product { get; set;}
}
I need to relate Schedule.Name with Products.Product
How can I do this in a simple way
I'm using EF Core 7.0
I read several posts, but usually the tutorials are referring to standard relationships. Where an ID field relates to another ID from another table
Thanks
I tried using data annotation and api fluent, but I couldn't get a result

Related

Entity Framework code first for object with collection of properties

I'm using C# and .NET Core with MySql and Entity Framework.
I have an object with a collection of properties. Like this:
public class Product
{
public int Id { get; set; }
public string Name { get; set; }
public IEnumerable<Property> Properties { get; set; }
}
public class Property
{
public int Id { get; set; }
public string Name { get; set; }
public object Value { get; set; }
}
In this case in the database, I should have tables Products, Properties (where property is described, like name and some additional info), and link table ProductProperties, storing product Id, property Id and Value.
But I can't figure out how to do this with a code-first approach.
How could I implement it with code first?
Is it a good way to create one more entity PropertyValue and store it under Product?
Something like this should give you a 1-to-many relationship, although you need to give Value a type, like string to store it in the database, often for dynamic solutions like this you would then maybe add a type to specify the type to deserialize into, but since you then deserialize anyway you could also just add things as json or something else in the db.
public class Product
{
public int Id {get; set;}
public string Name{get; set;}
public ICollection<Property> Properties{get; set;}
}
public class Property
{
public int Id {get; set;}
public string Name {get; set;}
public string Value {get; set;}
public int ProductId {get; set;}
}
Unless you are making a very dynamic system, it doesn't seem right to have the properties as a table, depends a lot of what you are making, and maybe key-value db might be a better tool for the job if thats what your main problem is, as with most complicated things, it depends.
This example is a convention based approach, which is why properties like ProductId have to be called exactly that. You can look at EntityTypeConfigurations if you want more control of names and relationships and such, or use data annotations to achieve the same job.
Ok so create a table like this:
public class ProductProprties
{
public int ProductId {get; set;}
public Product Product {get;set;}
public int PropertyId {get; set;}
public Property Property {get;set;}
//other props
}
If you are using EntityFramework Core, then you have to add this to your databse context as well:
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<ProdcutProprties>().HasKey(x => new { x.ProductId , x.PropertyId });
}

Map column to child object in EF Core 3

Giving the sample below, is there any way to have Address in the same table as User without making use of table splitting or owned types (eg like EF6 complex types)? The generated SQL prevents me from using it and complex types does not seem to be supported in EF Core 3:
public class User
{
public int Id { get; set; }
public Address Address { get; set; }
public string UserName { get; set; }
}
public class Address
{
public string StreetAddress { get; set; }
public string City { get; set; }
public string State { get; set; }
public string ZipCode { get; set; }
}
The only other options I see would be to map Address to its own table.
I will use a 1 to 0..1 relationship or include the properties in User directly.
Nevertheless, using Owned Types as a replacement for ComplexTypes like in EF 6 is horrible , if not completely useless from a SQL perspective, and I cannot see any reason for the joins. Maybe someone can clarify a proper justification for completness

EF foreign key reference using Id vs object

What is the difference between foreign key reference using Id vs object.
For example:
FK relation using Id
class Product
{
public int Id { get; set; }
public string Name { get; set; }
public string PhoneNumber { get; set; }
public int CategoryId { get; set; }
}
vs
FK relation using object
class Product
{
public int Id { get; set; }
public string Name { get; set; }
public string PhoneNumber { get; set; }
public Category Category { get; set; }
}
I have noticed from database that by using Id property the column essentially becomes non-null field.
Is that the only difference?
I think we can't query multiple tables at once i.e.querying related data?
When should I choose to use either options?
In your first example you're not adding a relationship, just an integer property named CategoryId.
In your second example, Entity Framework will create an integer column named "Category_ID", but you will be not be able to see this property in your model, so I like to explicitly add it my self and be able to use it along with the navigation property.
class Product
{
public int Id { get; set; }
public string Name { get; set; }
public string PhoneNumber { get; set; }
[ForeignKey("Category")]
public int CategoryId { get; set; }
public Category Category{get;set;}
}
This way you can also control the data type of CategoryId, so you could make it optional (nullable)
public int? CategoryId { get; set; }
*The foreign key data annotation is not needed, unless you have property or navigation property names that do not follow the naming convention for foreign key property names (Bardr), it doesn't harm to explicitly declare it either for clarity purposes
This implies that you're creating a 1 to many relationship (1-*) with products and categories, so in your Category class you would be adding a collection navigation property for products
class Category
{
public int Id{ get; set;}
public string Name{ get; set; }
...
public ICollection<Product> Products{get; set;}
}
Basically it depends on your use case and what type of loading related data you choose. Whether you use Id or object reference or full relationship on both sides (Id and object) it depends on your overall application architecture. If you wil go and use full or object reference everywhere, you will (probably) end up with a mess, and you won't know whether you should query for some entities using their repository or if it'll be okay to include them to some other query. I highly recommend you to take a look at this book, especially chapter 19 (Aggregates) and 21 (Repositories). There you have an in-depth explanation of what I meant and much more. (This does not only apply to applications built in DDD way)

EF Navigational Property through Different Properties Other Than Key

I'm working on mapping a legacy application with classes and use EntityFramework against it.
One flaw I have found in this legacy database is that multiple tables refer to a specific table through 2 different fields.
I'm not sure if this is possible and why I can't seem to find anything about it so I am here.
Here is a visual sample:
public class Term {
[Key]
public string Id { get; set; } // sample value: "12-34-56/78"
public string CleanId { get; set; } // sample value: "12345678" (basically the Id without special characters)
public DateTime Date { get; set; }
}
public class App {
public int Id { get; set; }
public string CleanTermId { get; set; } // foreign key is in Term class using the `CleanId` field
}
public class Question {
public int Id { get; set; }
public string TermId { get; set; } // foreign key is in Term class using the `Id` field
}
How can I properly add a navigational property from App and Question to the Term class using either DataAnnotations (preferred) to Fluent API? I do not require a navigational property from Term to App or Question but it's ok if your answer includes it.
Let me know if this is not clear.
Joining on fields other than Primary Key was something that isnt supported in EF versions prior to EF Core, however with your mention of it being a legacy app I doubt you would want to overhaul it to be able to use EF Core.
There was a User Voice request for the feature to be added Here which the response is that they had no plans to add this functionality into EF6 - so Core would be the only way to really do this.
In terms of your classes you would be able to link Question and Term as its based PK - FK, but the App to Term is basing both on non-PK fields, even with a Unique constraint on the DB, this is something not supported in EF prior to Core
Hi this is the correct Code:
public class Term
{
[Key]
public string Id { get; set; }
public string CleanId { get; set; }
public DateTime Date { get; set; }
}
public class App
{
public int Id { get; set; }
[ForeignKey("CleanTermId")]
public Term MyTerm { get; set; }
public string CleanTermId { get; set; }
}
public class Question
{
public int Id { get; set; }
[ForeignKey("TermId")]
public Term MyTerm { get; set; }
public string TermId { get; set; }
}

Entity Frame work Unique field issue

I am using EF Model first to create two entities
public class Brief
{
public int Id { get; set; }
public string Title { get; set; }
public string tId {get; set;}
public int SpeakerId { get; set; }
}
public class Speaker
{
public int Id { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
}
What I want to do is in Brief entity decorate tId field as Unique.
Second when I run entities as it is, it creates the database but it does not create foreigh key relation between SpeakerId in Briefs table and Speakers
Please let me know how
1. Decorate tId as unique
2. Why it is not creating the foreign key relation on SpeakerId and Speakers table?
Thanks
For problem number 2 you need to add a navigational property to your entity:
public class Brief
{
public int Id { get; set; }
public string Title { get; set; }
public string tId {get; set;}
public int SpeakerId { get; set; }
//Navigational property
public virtual Speaker Speaker { get; set;} 1 Brief has 1 Speaker
}
Depending on the Relationship this can also be public virtual ICollection<Speaker> Speakers { get; set;} Vice Versa for the Speaker entity:public virtual Brief Brief { get; set;} ` or the ICollection for n:m / 1:m relations
The unique constraint on non key columns should not be implemented as of yet based on http://entityframework.codeplex.com/workitem/299
Further reading / related questions:
Setting unique Constraint with fluent API?
http://bit.ly/OcE2HV
See Unique key with EF code first
Dependent on the EF version you can set an attribute on the property.
Use a navigational property so EF can determine the relation.
Note that the virtual keyword denotes lazy loading. See Entity Framework Code First Lazy Loading

Categories

Resources