gpt4 book ai didi

c# - Fluent Api - M :M relationship with two 1:M properties. 怎么样?

转载 作者:太空宇宙 更新时间:2023-11-03 13:18:49 25 4
gpt4 key购买 nike

我有这个模型。一名运动员有多种锻炼方式和多种训练计划。一项锻炼可以包含在许多训练计划中。一天可以进行多次锻炼,这就是为什么我需要在 M:M 关系中添加额外字段 DateToPerform 的原因。我怎样才能完成它,这是我的模型:

public class Athlete
{
public int Id {get; set;}
public string Name {get; set;}
public virtual List<Workout> Workouts {get; set;}
public virtual List<TrainingPlan> TrainingPlans {get; set;}
}

public class Workout
{
public int Id {get; set;}
public string Name {get; set;}
public virtual Athlete Athlete {get; set;} //Athlete owner of the WO.
public virtual List<TrainingPlan> TrainingPlans {get; set;} //Plans where WO is.
}

public class TrainingPlan
{
public int Id {get; set;}
public string Name {get; set;}
public virtual Athlete Athlete {get; set;} //Athlete owner of this TP.
public virtual List<Workout> Workouts {get; set;} //Workouts in this plan.
}

因为我需要额外的字段,所以我读到我应该将关系提升到实体,这就是我结束这样做的方式:

public class TrainingPlanWorkout
{
public int Id {get; set;}
public virtual TrainingPlan TrainingPlan { get; set; }
public virtual Workout Workout { get; set; }
public DateTime DateToPerform { get; set; }
}

现在我使用 fluen´t API 定义所有这些:

//I define primary keys.
modelBuilder.Entity<Athlete>().HasKey(x => x.Id);
modelBuilder.Entity<TrainingPlan>().HasKey(x => x.Id);
modelBuilder.Entity<Workout>().HasKey(x => x.Id);
modelBuilder.Entity<TrainingPlanWorkout>().HasKey(x => x.Id);

modelBuilder.Entity<Athlete>().HasMany(a => a.AthleteTrainingPlans)
.WithRequired(t=>t.Athlete)
.WillCascadeOnDelete(true);

modelBuilder.Entity<Athlete>().HasMany(m => m.AthleteWorkouts)
.WithRequired(m=>m.Athlete)
.WillCascadeOnDelete(true);


modelBuilder.Entity<TrainingPlanWorkout>().HasRequired(t => t.TrainingPlan);
modelBuilder.Entity<TrainingPlanWorkout>().HasRequired(t => t.Workout);

当我运行该应用程序时,我收到以下错误:

Introducing FOREIGN KEY constraint 'FK_dbo.TrainingPlanWorkouts_dbo.Workouts_Workout_Id' on table 'TrainingPlanWorkouts' may cause cycles or multiple cascade paths. Specify ON DELETE NO ACTION or ON UPDATE NO ACTION, or modify other FOREIGN KEY constraints.

我认为我把事情复杂化了,完成这种情况的最佳方法是什么?

谢谢。

最佳答案

我使用以下代码实现了您的问题,主要区别在于关系实体的模型构建器。

namespace ConsoleApplication1
{
class Program
{
public class Athlete
{
public int Id { get; set; }
public string Name { get; set; }

private ICollection<Workout> workouts;
public virtual ICollection<Workout> Workouts
{
get { return workouts ?? (workouts = new HashSet<Workout>()); }
set { workouts = value; }
}

private ICollection<TrainingPlan> trainingPlans;
public virtual ICollection<TrainingPlan> TrainingPlans
{
get { return trainingPlans ?? (trainingPlans = new HashSet<TrainingPlan>()); }
set { trainingPlans = value; }
}
}

public class TrainingToPerform
{
public int Id { get; set; }

public DateTime DateToPerform { get; set; }

public virtual TrainingPlan TrainingPlan { get; set; }
public virtual Workout Workout { get; set; }
}

public class Workout
{
public int Id { get; set; }
public string Name { get; set; }

public virtual Athlete Athlete { get; set; }

private ICollection<TrainingToPerform> trainingsToPerform;
public virtual ICollection<TrainingToPerform> TrainingsToPerform
{
get { return trainingsToPerform ?? (trainingsToPerform = new HashSet<TrainingToPerform>()); }
set { trainingsToPerform = value; }
}
}

public class TrainingPlan
{
public int Id { get; set; }
public string Name { get; set; }

public virtual Athlete Athlete { get; set; }

private ICollection<TrainingToPerform> trainingsToPerform;
public virtual ICollection<TrainingToPerform> TrainingsToPerform
{
get { return trainingsToPerform ?? (trainingsToPerform = new HashSet<TrainingToPerform>()); }
set { trainingsToPerform = value; }
}
}


public class Db3 : DbContext
{
public Db3()
{

}

public DbSet<Athlete> Athletes { get; set; }
public DbSet<Workout> Workouts { get; set; }
public DbSet<TrainingPlan> TrainingPlans { get; set; }
public DbSet<TrainingToPerform> TrainingsToPerform { get; set; }

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);

modelBuilder.Entity<TrainingPlan>()
.HasKey(x => x.Id);

modelBuilder.Entity<Workout>()
.HasKey(x => x.Id);

modelBuilder.Entity<Athlete>()
.HasKey(x => x.Id);

modelBuilder.Entity<Athlete>()
.HasMany(a => a.TrainingPlans)
.WithRequired(t => t.Athlete)
.WillCascadeOnDelete(true)
;

modelBuilder.Entity<Athlete>()
.HasMany(a => a.Workouts)
.WithRequired(t => t.Athlete)
.WillCascadeOnDelete(true)
;

modelBuilder.Entity<TrainingToPerform>()
.HasKey(x => x.Id);

modelBuilder.Entity<TrainingToPerform>()
.HasRequired(t => t.Workout)
.WithOptional()
.WillCascadeOnDelete(false)
;

modelBuilder.Entity<TrainingToPerform>()
.HasRequired(t => t.TrainingPlan)
.WithOptional()
.WillCascadeOnDelete(false)
;
}
}

static void Main(string[] args)
{

var db = new Db3();

var a = new Athlete { Name = "a6"};
var w = new Workout { Name = "w6", Athlete = a };
var t = new TrainingPlan { Name = "t6", Athlete = a };
db.Athletes.Add(a);
db.Workouts.Add(w);
db.TrainingPlans.Add(t);
db.SaveChanges();

var wtp = new TrainingToPerform { TrainingPlan = t, Workout = w, DateToPerform = DateTime.Now };

w.TrainingsToPerform.Add(wtp);
t.TrainingsToPerform.Add(wtp);


db.TrainingsToPerform.Add(wtp);

db.SaveChanges();

Console.WriteLine(db.TrainingsToPerform.First().Workout.Name);

}
}
}

关于c# - Fluent Api - M :M relationship with two 1:M properties. 怎么样?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25062857/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com