Reputation: 1852
public class Order
{
public int Id { get; set; }
public string Type { get; set; }
}
Order
has the composite key (Id, Type)
.
public class SalesOrderItem
{
public int Id { get; set; }
public int OrderId { get; set; }
public Order Order { get; set; }
}
SalesOrderItem
has the key Id
.
I want to configure a relation between SalesOrderItem
and Order
. SalesOrderItem
does not have an OrderType
column that can be used to create the composite key for the relation. OrderType
is always SAL
when working with SalesOrderItem
.
I have tried to configure the relation by setting a constant in the foreign key part:
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder
.Entity<Order>()
.HasKey(o => new { o.Id, o.Type });
modelBuilder
.Entity<SalesOrderItem>()
.HasKey(s => s.Id);
modelBuilder
.Entity<Order>()
.HasMany<SalesOrderItem>()
.WithOne(salesOrderItem => salesOrderItem.Order)
.HasForeignKey(salesOrderItem => new {salesOrderItem.OrderId, Type = "SAL"});
}
This does not work.
What can I do?
Upvotes: 2
Views: 1482
Reputation: 319
bit different view on the same problem. (i am moving project from plain sqlrecord to ef core, so it is data first. and data structure can't be modified for now. so it is not optimal in many parts)
i have tasks, which may have few steps and each step may have a comment. comments are stored in separate table. and other objects in database may have comments in the same table. so the data structure is
public partial class Comment
{
public int Id { get; set; }
public int RefType { get; set; }
public int RefId { get; set; }
public int? RefId1 { get; set; }
public string Comment1 { get; set; }
}
where RefType is referring object type
Refid is id of referring object
RefId1 is second id if needed
enities (partially)
public enum RefType : int { UNKNOWN = 0, TASK, TaskStep };
public partial class TaskHist
{
public int TaskId {get;set;}
public ICollection<TaskStep> TaskSteps { get; set; }
}
public partial class TaskStep
{
public int Id { get; set; }
public int TaskId { get; set; }
public int StepNum { get; set; }
public tsComment comment { get; set; }
}
// tsComment only for descriminator
public class tsComment : Comment
{
}
model configuration partially
modelBuilder.Entity<Comment>(entity =>
{
entity.HasKey(c => c.Id);
entity.HasDiscriminator<int>(c=>c.RefType)
.HasValue<Comment>(0)
.HasValue<tsComment>((int)RefType.TaskStep)
.IsComplete(false);
});
modelBuilder.Entity<TaskHist>(entity =>
{
entity.HasKey(t => t.TaskId);
entity.HasMany(t=>t.TaskSteps).WithOne().HasForeignKey(t=>t.TaskId);
});
modelBuilder.Entity<TaskStep>(entity =>
{
entity.HasOne(t => t.comment).WithOne()
.HasForeignKey<TaskStep>(c=> new {c.TaskId, c.StepNum})
.HasPrincipalKey<tsComment>(c=> new {c.RefId, c.RefId1});
});
Upvotes: 0
Reputation: 10790
You cannot use constant as a reference but instead you can derive another table like this :
public class SalesOrder : Order
{
}
public class SalesOrderItem
{
public int Id { get; set; }
public int OrderId { get; set; }
public SalesOrder Order { get; set; }
}
and configure your salesorder like this
modelBuilder.Entity<Order>()
.HasDiscriminator(t => t.Type)
.HasValue<SalesOrder>("SAL");
then map with just foreign key to sales order
modelBuilder
.Entity<Order>()
.HasMany<SalesOrderItem>()
.WithOne(salesOrderItem => salesOrderItem.Order)
.HasPrincipalKey(salesOrderItem => salesOrderItem.OrderId);
EDIT : Since it has composite index using principal key is the option as @Jogge commented.
Upvotes: 2