下面你可以看到SQL应该使用[ClassId1]而不是[Class1_ClassId]加入,因为后者不存在。
我很确定我可以使用Fluent API来纠正这个问题但不确定使用哪种方法。
生成SQL
SELECT ...
FROM [dbo].[School] AS [Extent1]
LEFT OUTER JOIN [dbo].[Student] AS [Extent2] ON [Extent1].[SchoolId] = [Extent2].[SchoolId]
LEFT OUTER JOIN [dbo].[Class] AS [Extent3] ON [Extent2].[Class1_ClassId] = [Extent3].[ClassId]
LEFT OUTER JOIN [dbo].[Class] AS [Extent4] ON [Extent2].[Class2_ClassId] = [Extent4].[ClassId]
WHERE ...
表
School
- SchoolId
- Name
- StudentId
Student
- StudentId
- Name
- Class1Id
- Class2Id
Class
- ClassId
- Name
模型
public class School
{
[Required]
public long SchoolId { get; set; }
[Required]
public string Name { get; set; }
[Required]
public long StudentId { get; set; }
public virtual Student Student { get; set; }
}
public class Student
{
[Required]
public long StudentId { get; set; }
[Required]
public string Name { get; set; }
[Required]
public long ClassId1 { get; set; }
public long? ClassId2 { get; set; }
public virtual Class Class1 { get; set; }
public virtual Class Class2 { get; set; }
}
public class Class
{
[Required]
public long ClassId { get; set; }
[Required]
public string Name { get; set; }
}
答案 0 :(得分:3)
[Required]
public long ClassId1 { get; set; }
public long? ClassId2 { get; set; }
public virtual Class Class1 { get; set; }
public virtual Class Class2 { get; set; }
您尚未设置这些属性之间的任何关系。由于您还没有为Class1
或Class2
定义外键列,因此它会为您创建它们:Class1_ClassId
和Class2_ClassId
。创建迁移应该为您创建这些列;但是您最终会得到重复项(例如Class1Id
和Class1_ClassId
)。
我相信如果名称以Id
结尾,则EntityFramework将解析属性之间的关系。这意味着您的设置应该是:
[Required]
public long Class1Id { get; set; }
public long? Class2Id { get; set; }
public virtual Class Class1 { get; set; }
public virtual Class Class2 { get; set; }
然而,我发现明白它更好 - 纯粹是为了可读性并确保EF不会试图变得太聪明。我这样写:
[Required]
public long ClassId1 { get; set; }
public long? ClassId2 { get; set; }
[ForeignKey("ClassId1")]
public virtual Class Class1 { get; set; }
[ForeignKey("ClassId2")]
public virtual Class Class2 { get; set; }
这应该在数据库中正确设置外键关系。
答案 1 :(得分:0)
我认为实体框架是从你的linq构造这个SQL的,因为模型中类之间的关系不清楚。
根据您的模型,School
只有一个Student
,Student
不知道他参加了哪个School
,并且必须拥有一个Class
class
{1}},可能还有第二个。 School
不知道Students
是哪个Class
,School
中的Students
。
您确定您的型号吗?
我认为School
会有零个或多个Classes
。 class
也有零个或多个School
。每个Student
都是Classes
中的一个类。
在数据库术语中,这是典型的一对多关系。见Entity Framework Configure One-to-Many Relationship
此外,Class
出现零个或多个Students
,class School
{
public int Id {get; set;}
// a School has many Students:
public virtual ICollection<Student> Students {get; set;}
// a School has many Classes:
public virtual ICollection<Class> Classes {get; set;}
...
}
public class Student
{
public int Id {get; set;}
// A student belongs to one School via Foreign Key
public int SchoolId {get; set;}
public virtual School School {get; set;}
// A student attends many classes
public virtual ICollection<Class> Classes {get; set;}
...
}
class Class
{
public int Id {get; set;}
// a class belongs to one School via foreign key:
public int SchoolId {get; set;}
public virtual School School {get; set;}
// a class has many Students
public virtual ICollection<Student> Students {get; set;}
...
}
有一个或多个class MyDbContext : DbContext
{
public DbSet<School> Schools {get; set;}
public DbSet<Student> Students {get; set;}
public DbSet<Class> Classes {get; set;}
}
。
在数据库术语中,这是典型的多对多关系。请参阅:Entity Framework configure many-to-many relationship
这些文章还描述了学校,学生和学生。总结类定义应该是:
Class
在此之后,DbContext将如下:
Classs
如果你这样建模,实体框架将自动识别学校和学生之间的一对多关系,并为它创建适当的外键。它还将识别学生和班级之间的多对多关系。它甚至会为多对多创建一个表,这在LINQ查询中是不需要的。
Entity Framework uses default conventions如果您遵循它们,您将无需告诉模型有关表名和列名,主键和外键等信息。
回到你的问题
您想告诉您的模型它应该为属性使用某个列名,而不是它从您的类关系构造的列名。
这可以使用您班级中的数据注释,或使用DbContext中的Fluent API来完成。我更喜欢使用Fluent Api,因为它允许您在不同的数据库结构中使用相同的类而无需更改类。如果您需要不同的表名,或主键的不同名称,小数的不同精度等,您所要做的就是创建一个新的DbContext。您不必更改课程,课程用户也不会注意到更改。
在您的情况下:指定表名而不是默认表名。
在我的示例中,A Classes
将放在表格 class MyDbContext : DbContext
{
public DbSet<School> Schools {get; set;}
public DbSet<Student> Students {get; set;}
public DbSet<Class> Classes {get; set;}
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
// Entity Class should be put in table Classes
modelBuilder.Entity<Class>().ToTable("Classes");
// property Student.ClassId in column "ClassId1"
modelBuilder.Entity<Student>() // from class Student
.Property(student => student.ClassId) // take property ClassId
.HasColumnName("ClassId1"); // give it the column name "ClassId1"
}
}
中,当然您在表struct myTempSubStruct
{
u32 v1;
u16 v2;
u8 v3;
};
struct myTempStruct
{
u8 v4;
u8 v5;
myTempSubstruct v6;
};
中需要它:
from robot.libraries.BuiltIn import BuiltIn
class generated_messages(object):
ROBOT_LIBRARY_SCOPE = 'GLOBAL'
def __init__(self):
self.syscom = BuiltIn().get_library_instance('syscom_rammbock')
def myStruct(self, name):
self.syscom.new_struct('myStruct', name)
self.myTempStruct('myTempStruct')
self.syscom.end_struct()
def myTempReq(self):
return myStruct