EF CORE CODE FIRST PRIMARY KEY COMPOSITE KEY PRIMARY KEY - sql

I would like to know if someone knows how to make a table with a primary key composed of two columns, where the first column is sent by me, and the second is generated from the first
public class Person
{
public int idPerson { get; set; }
public string name { get; set; }
}
public class PersonAdress
{
public int idPerson { get; set; }
public int DireccionId { get; set; }
public string reference { get; set; }
}
I am looking for the incremental of the second column to be if the first column changes

how to make a table with a primary key composed of two columns
You can add the following code by fluent api in dbContext's OnModelCreating method :
modelBuilder.Entity<PersonAdress>().HasKey(sc => new { sc.idPerson , sc.DireccionId });
You can also have a reference for this.

Related

Link two tables with a one-to-one relationship, using the same unique key

I have two tables that need to be linked one to one by the key field email.
When I try to do this, I get an error like this:
Cannot use table 'UserSettings' for entity type 'UserSettings' since it is being used for entity type 'UserSettings' and potentially other entity types, but there is no linking relationship. Add a foreign key to 'UserSettings' on the primary key properties and pointing to the primary key on another entity type mapped to 'UserSettings'.
how I tried to implement it:
public class UserSettingsConfiguration : IEntityTypeConfiguration<UserSettings>
{
public void Configure(EntityTypeBuilder<UserSettings> builder)
{
builder.HasKey(n => n.Email);
builder.HasOne(n => n.User)
.WithOne(u => u.UserSettings)
.HasForeignKey<UserSettings>(k => k.Email)
.HasPrincipalKey<UserSettings>(k => k.Email);
}
}
UserSettings and User entities:
public class User
{
public string Email { get; set; }
public DateTime RegistrationDate { get; set; }
public string Image { get; set; }
public UserSettings UserSettings { get; set; }
}
public class UserSettings
{
public string Email { get; set; }
public int LanguageId { get; set; }
public User User { get; set; }
}

Two FK's pointing to the same column in another table

I have
public class Customer
{
public int Id { get; set; }
public int RepresentativeId { get; set; }
public int ChargeRepresentativeId { get; set; }
}
public class Representative
{
public int Id { get; set; }
public string Number { get; set; }
public string Name { get; set; }
}
Every Customer has its own Representative represented with RepresentativeId column, but also in certain scenarios I want to create new Customer with both RepresentativeId and its ChargeRepresentativeId.
I already have a FK constraint applied on RepresentativeId column
ALTER TABLE [Representatives] ADD CONSTRAINT [FK_Customers_Representatives]
FOREIGN KEY([RepresentativeId]) REFERENCES [Representative] ([Id])
How can I force ChargeRepresentativeId to be valid data which exists in the Representatives table (the case I already have for the RepresentativeId)?

EF Core composite foreign key and constraint

In my project I have noticed that I will be have a lot of dictionaries with the same structure:
shortcut
full name for tooltip
which will be used on many different business forms.
I started to thing that there is no sense to keep all of them in separate tables.
It is better to keep all of them in one table and provide an additional column (DictionaryType) which will separate them in the case of asking the database for data?
So one repository with such method
public class DictionaryEntity
{
public Guid Id { get; set; }
public string Name { get; set; }
public string FullName { get; set; }
public DictionaryType Type { get; set; }
}
public async Task<IEnumerable<DictionaryEntity> GetDictionaries(DictionaryType type)
{
return await _dbContext.Dictionaries.Where(d => d.DictionaryType == type).ToArrayAsync();
}
If new dictionaries appear, I need to only extend DictionaryType and I don't need to worry about database changes or repo/service/controller changes.
For now it is nice and easy, but... I would like to configure foreign key in business entities in that way:
public class CarEntity
{
public Guid Id { get; set; }
public Guid ModelTypeId { get; set;}
public DictionaryEntity ModelType { get; set;}
public Guid PetrolTypeId { get; set;}
public DictionaryEntity PetrolType { get; set;}
}
How to configure in EF Core, foreign key in that way where:
CarEntity.ModelTypeId points to DictionaryEntity.Id and DictionaryEntity.Type = DctionaryType.ModelType ?
CarEntity.PetrolTypeId points to DictionaryEntity.Id and DictionaryEntity.Type = DctionaryType.PetrolType ?
I read, that there is something like a composite foreign key, so I could do FK on { dict.Name, dict.Type } but it demands from me to keep in CarEntity as many properties as composite foreign key have.
Is there a chance to do unique constraint across multiple tables ?
Something like this:
modelBuilder.Entity<CarEntity>()
.HasCheckConstraint("CK_ModelType", "[ModelTypeId] IS NOT NULL AND [Document].[Type] = 'ModelType'", c => c.HasName("CK_ModelType_Dictionary"));

Asp.net core Add Soft delete by modelBuilder.Entity<DependenciaDisciplina>().Property<bool>("isDeleted"); but isDeleted as composite key

I insert the soft delete flag with
modelBuilder.Entity<DependenciaDisciplina>().Property<bool>("isDeleted");
But i need to add it as a composite key
Can somebody help me?
I insert the soft delete flag with
modelBuilder.Entity<DependenciaDisciplina>().Property<bool>("isDeleted");
But i need to add it as a composite key
To set the Composite Keys using the Fluent API, we have to use the HasKey() method.
After check the HasKey() method definition, we can see that the parameter should be a string array or an expression.
So, you could use the set the composite key like this (change the Car model to your model):
modelBuilder.Entity<Car>().Property<bool>("isDeleted");
modelBuilder.Entity<Car>().HasKey(new string[] { "CarId", "isDeleted" });
The Car model:
public class Car
{
[Key]
public int CarId { get; set; }
public string CarName { get; set; }
public string LicensePlate { get; set; }
public string Make { get; set; }
public string Model { get; set; }
}
Then, after migration, the result like this:

One-to-Many relation to existed table in EF6: The ALTER TABLE statement conflicted with the FOREIGN KEY constraint

So now I'm trying to use Code first approach with a couple of existed tables.
So before now I have an existed table with model:
[Table("Existed1")]
public class TimeSerieEntity
{
[Key]
[Column(Order = 0)]
[StringLength(3)]
public string TsId { get; set; }
[Key]
[Column(Order = 1, TypeName = "date")]
public DateTime Date { get; set; }
public double Value { get; set; }
}
And this entity illustrate time series element. So Now I need to add new Entity which has One-to-Many relation with this data. So I add class
public class TSRootEntity
{
[Key]
[StringLength(3)]
public string Code { get; set; }
public virtual ICollection<TimeSerieEntity> Values { get; set; }
}
and change TimeSerieEntity to this one:
[Table("Existed1")]
public class TimeSerieEntity
{
[Key, ForeignKey("TSMD")]
[Column(Order = 0)]
[StringLength(3)]
public string TsId { get; set; }
[Key]
[Column(Order = 1, TypeName = "date")]
public DateTime Date { get; set; }
public double Value { get; set; }
public virtual TSRootEntity TSMD { get; set; }
}
and add the following mapping:
`modelBuilder.Entity<TSRootEntity>()
.HasMany(c => c.Values)
.WithRequired(ts => ts.TSMD)
.WillCascadeOnDelete(false);
But when I trying to run migration it fails with error:
{"'PK_dbo.Existed1' is not a constraint.\r\nCould not drop constraint. See previous errors."}
Please, help me to fix this.
For some reason it's try to use PK_dbo.Existed1 but there is no such Constraint in DB, but there is PK_Existed1 Why EF add this dbo prefix?
UPD2:
I solved 1st problem just with renaming PK constraint. But now I have different exception:
The ALTER TABLE statement conflicted with the FOREIGN KEY constraint "FK_dbo.Existed1_dbo.TSRootEntity_TsId". The conflict occurred in database "testdb", table "dbo.TSRootEntity", column 'Code'.
Ok. Found the problem. So last error caused because of Existed1 already have data, and TSRootEntity is empty. So it's try to map actuall foreign keys, to non existed primary keys. And that's make it fails.
So to solve that, we need prefill TSRootEntity as well. The question is - what is the most elegant way to do that?