实体框架中没有自动生成代码的数据库优先方法 [英] Database-first approach in Entity Framework without auto generated code

查看:152
本文介绍了实体框架中没有自动生成代码的数据库优先方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想知道,如果有任何方式,
提前使用数据库优先方法与手动生成的类(模型)(就像代码优先方法)一样,
但不使用自动生成实体框架使用数据库优先方法创建的代码?
我有3个类(前两个学生和课程有很多关系),代表模型:
第一个是学生:

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

public string Name {get; set;}

public DateTime BirthDate {get; set;}

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

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

然后课程:

  public class Course 
{
public int CourseID {get;组; }

public string CourseName {get;组; }

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


public Course()
{
StudentToCourses = new List< StudentToCourse>();
}

}

和关系/中级课程附加属性StudentToCourse:

  public class StudentToCourse 
{
[Key,Column(Order = 0)]
public int StudentID {get;组; }
[Key,Column(Order = 1)]
public int CourseID {get;组; }
[Key,Column(Order = 2)]
public DateTime Date {get;组; }

public virtual Student Student {get;组; }

public virtual Course Course {get;组; }

// public ICollection< Student>学生{get;组; }

// public ICollection< Course>课程{get;组; }

public int Grade {get;组; }

}

另外,我创建了数据库,在VS中使用LocalDb功能2013年



我有3个表:
课程:

  CREATE TABLE [dbo]。[课程] 

[CourseID] INT NOT NULL主键标识,
[CourseName] NVARCHAR(100)NOT NULL,

学生:

  CREATE TABLE [dbo]。[学生] 

[StudentID] INT NOT NULL主键标识,
[名称] NVARCHAR(50)NOT NULL,
[出生日期] DATETIME NOT NULL,

关系表StudentsToCourses:

  CREATE TABLE [dbo]。[StudentsToCourses] 

[StudentID] INT参考学生(StudentID)NOT NULL,
[CourseID] INT参考课程(CourseID)NOT NULL,
[日期] DATETIME NOT NULL,
[成绩] INT NOT NULL,
PRIMARY KEY(StudentID,CourseID,Date)

不幸的是,我没有运气这个方法,我确实得到学生的数据,但是我没有从关系表中收到数据,我不能收到每个学生的所有相关成绩。



我搜索了相关的主题在谷歌和stackoverflow,但所有这些主题对我来说没有帮助,虽然上面的例子我发现在这个话题

解决方案

As我怀疑,问题不在于您是否可以独立拥有数据库和类模型。当然可以!所有这些生成工具和迁移的东西只能达到一个目标:使生活更轻松,帮助您保持两个模型的同步。但是你也可以自己做这个工作。最终的结果总是:两个模型 - 在运行时 - 不要互相交互。 (不要互动?不,不是这样,必须有一个中间人,一个ORM,连接两个世界。)



你没有得到的原因数据是因为不会发生延迟加载。您的陈述是

  var listOfGrades = _context.Students.Where(s => s.Name.StartsWith(J) )
.FirstOrDefault()。StudentToCourses;

这需要懒惰加载,因为 FirstOrDefault()语句执行查询的第一部分。它呈现一个学生,随后 StudentToCourses 被访问。但是这些不加载,因为集合不是 virtual 。应该是

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

这将启用EF来覆盖能够延迟加载的动态代理对象中的集合。 / p>

但是,当然,在一个语句中获取集合效率更高,例如:

 
.Where(s => s.Name.StartsWith(J))
。 FirstOrDefault()StudentToCourses。


I wonder, if there is any way , to use Database-first approach with manually generated classes (models) in advance(just like Code-first approach), but without using auto-generated code which Entity Framework creates using Database-first approach? I have 3 Classes(first two of them Student and Courses have many to many relationship), which represents models: First one is Student:

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>();
    }
}

Then Course:

    public class Course
{
    public int CourseID { get; set; }

    public string CourseName { get; set; }

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


    public Course()
    {
        StudentToCourses = new List<StudentToCourse>();
    }

}

And Relation/Intermediate Class with additional properties StudentToCourse:

    public class StudentToCourse
{
    [Key, Column(Order = 0)]
    public int StudentID { get; set; }
    [Key, Column(Order = 1)]
    public int CourseID { get; set; }
    [Key, Column(Order = 2)]
    public DateTime Date { get; set; }

    public virtual Student Student { get; set; }

    public virtual Course Course { get; set; }

    //public ICollection<Student> Students { get; set; }

    //public ICollection<Course> Courses { get; set; }

    public int Grade { get; set; }

}

Also, i created Database, using LocalDb feature in VS 2013

I have 3 Tables: Courses:

CREATE TABLE [dbo].[Courses]
(
[CourseID] INT NOT NULL PRIMARY KEY IDENTITY,
[CourseName] NVARCHAR(100) NOT NULL,
)

Students:

CREATE TABLE [dbo].[Students]
(
[StudentID] INT NOT NULL PRIMARY KEY IDENTITY,
[Name] NVARCHAR(50) NOT NULL,
[BirthDate] DATETIME NOT NULL,
)

Relation Table StudentsToCourses:

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) 
)

Unfortunately, i have no luck with this approach, i do get students' data but i don't receive data from relational table and i can't receive all related grades per student.

I searched for related topics in google and in stackoverflow , but all those topics weren't helpful for me, although the example above i found in this topic.

解决方案

As I suspected, the problem is not whether or not you can have a database and a class model independently. Of course you can! All these generation tools and migration stuff only serve one goal: making life easier, help you keeping both models in sync. But you can do that job yourself just as well. The end result is always: two models that – at runtime – don't interact with each other whatsoever. (Don't interact? No, not as such. There must be a middleman, an ORM, to connect both worlds.)

The reason why you don't get data is because lazy loading does not occur. Your statement is

var listOfGrades = _context.Students.Where(s => s.Name.StartsWith("J"))
                   .FirstOrDefault().StudentToCourses;

This requires lazy loading, because the FirstOrDefault() statement executes the first part of the query. It renders a Student of which subsequently the StudentToCourses are accessed. But these don't load because the collection is not virtual. It should be

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

This enables EF to override the collection in a dynamic proxy object that is capable of lazy loading.

But of course is is more efficient to get the collection in one statement, for example:

var listOfGrades = _context.Students.Include(s => s.StudentToCourses)
                   .Where(s => s.Name.StartsWith("J"))
                   .FirstOrDefault().StudentToCourses;

这篇关于实体框架中没有自动生成代码的数据库优先方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆