C# 实体框架中的数据库优先方法,无需自动生成代码

C# 实体框架中的数据库优先方法,无需自动生成代码,c#,sql,entity-framework,C#,Sql,Entity Framework,我不知道有没有办法, 要使用数据库优先方法提前手动生成类(模型)(就像代码优先方法一样), 但如果不使用自动生成的代码,哪个实体框架使用数据库优先的方法创建? 我有3个班(前两个班是学生班,课程之间有多对多关系),这代表了模型: 第一个是学生: public class Student { public int StudentID { get; set;} public string Name { get; set;} public DateTime BirthD

我不知道有没有办法, 要使用数据库优先方法提前手动生成类(模型)(就像代码优先方法一样), 但如果不使用自动生成的代码,哪个实体框架使用数据库优先的方法创建? 我有3个班(前两个班是学生班,课程之间有多对多关系),这代表了模型: 第一个是学生:

public class Student
{
    public int StudentID  { get; set;}

    public string Name  { get; set;}

    public DateTime BirthDate { get; set;}

    public ICollection<StudentToCourse> StudentToCourses { get; set; }

    public Student()
    {
        StudentToCourses = new List<StudentToCourse>();
    }
}
学生:

CREATE TABLE [dbo].[Students]
(
[StudentID] INT NOT NULL PRIMARY KEY IDENTITY,
[Name] NVARCHAR(50) NOT NULL,
[BirthDate] DATETIME NOT NULL,
)
学生与课程的关系表:

CREATE TABLE [dbo].[StudentsToCourses]
(
[StudentID] INT REFERENCES Students(StudentID) NOT NULL,
[CourseID] INT REFERENCES Courses(CourseID) NOT NULL,
[Date] DATETIME NOT NULL,
[Grade] INT NOT NULL,
PRIMARY KEY (StudentID, CourseID, Date) 
)
不幸的是,我并没有使用这种方法,我确实得到了学生的数据,但我并没有从关系表中收到数据,我也不能收到每个学生的所有相关分数


我在google和stackoverflow中搜索了相关主题,但所有这些主题对我都没有帮助,尽管我在这里找到了上面的例子。

是的,你可以。您只需要一个没有初始化策略的上下文(因此它不会尝试创建或迁移现有数据库):

公共类现有DatabaseContext:DbContext
{
公共现有数据库上下文()
:base(“现有数据库连接字符串名称”)
{
Database.SetInitializer(null);
}
//这里的dbset用于表示现有数据库表的“代码优先”类
}

请记住,此上下文无法执行迁移或任何其他形式的初始化,因此,如果其中也有实际的true code first表,则需要单独的上下文来管理这些表。

正如我所怀疑的,问题不在于是否可以独立地拥有数据库和类模型。你当然可以!所有这些生成工具和迁移工具只服务于一个目标:让生活更轻松,帮助您保持两个模型的同步。但你也可以自己做这项工作。最终的结果总是:两个模型——在运行时——无论如何都不会相互影响。(不要互动?不,不是这样。必须有一个中间人,一个ORM,来连接两个世界。)

无法获取数据的原因是不会发生延迟加载。你的陈述是正确的

var listOfGrades = _context.Students.Where(s => s.Name.StartsWith("J"))
                   .FirstOrDefault().StudentToCourses;
这需要延迟加载,因为
FirstOrDefault()
语句执行查询的第一部分。它呈现一个
Student
,随后可以访问其中的
StudentToCourses
。但是这些不会加载,因为集合不是虚拟的。应该是

public virtual ICollection<StudentToCourse> StudentToCourses { get; set; }

为什么代码优先不适合你?是的,你可以,但为什么?是的,它可以做到,但真正的问题是为什么?数据库首先允许EF确保一切正常工作。代码首先要求您熟悉对象图并相应地创建所有内容。混合型不是一个好主意,一个原因是,一个更改实际上需要比任何一个默认值更多的工作。很可能这是一个,也就是说,你认为这个你无法使用的解决方案将解决一个根本问题,但你没有描述根本问题。我想尽量简化它,同时我想完全控制数据库。你所要求的并不简单。您可以使用“数据库优先”和“代码优先”来完全控制数据库。谢谢你的回答,但这对我不起作用,我仍然得到一个空的“公共ICollection StudentToCourses”集合。我认为中间类\表有一些问题,因为EF不喜欢它。谢谢你的回答,但是。。。首先,据我所知,Include方法获取字符串作为其传入参数。其次,我实际上将StudentToCourses定义为虚拟的(正如您所建议的),现在我得到一个异常“无效对象名'dbo.StudentToCourses'”,下面是代码:
var studentGrades=\u context.Students.Include(“StudentToCourses”).Where(s=>s.name==“John”).FirstOrDefault().StudentToCourses
include参数取决于您使用的EF版本,或者您是否有使用System.Data.Entity.DbExtensions的
。DDL脚本中的表名是
StudentsToCourses
(带“s”的学生)。我使用的是EF 6.0,关于System.Data.Entity.DbExtensions,很好,谢谢,我忘了这个,你说得对。我也尝试了学生们的课程,这给我带来了同样的例外。
CREATE TABLE [dbo].[StudentsToCourses]
(
[StudentID] INT REFERENCES Students(StudentID) NOT NULL,
[CourseID] INT REFERENCES Courses(CourseID) NOT NULL,
[Date] DATETIME NOT NULL,
[Grade] INT NOT NULL,
PRIMARY KEY (StudentID, CourseID, Date) 
)
public class ExistingDatabaseContext : DbContext
{
    public ExistingDatabaseContext()
        : base("ExistingDatabaseConnectionStringName")
    {
        Database.SetInitializer<ExistingDatabaseContext>(null);
    }

    // DbSets here for your "code-first" classes that represent existing database tables
}
var listOfGrades = _context.Students.Where(s => s.Name.StartsWith("J"))
                   .FirstOrDefault().StudentToCourses;
public virtual ICollection<StudentToCourse> StudentToCourses { get; set; }
var listOfGrades = _context.Students.Include(s => s.StudentToCourses)
                   .Where(s => s.Name.StartsWith("J"))
                   .FirstOrDefault().StudentToCourses;