简体   繁体   English

具有MVC4的实体框架5

[英]Entity Framework 5 with MVC4

I am building a website with a rather complex SQL database. 我正在用一个相当复杂的SQL数据库构建一个网站。
I made a Query class, which holds multiple primitive fields (which all work fine) and also multiple List<SomeType> . 我制作了一个Query类,其中包含多个基本字段(都可以正常工作)以及多个List<SomeType> SomeType is also defined under the Models folder in my solution. 我的解决方案中的Models文件夹下也定义了SomeType It also holds single instances of SomeType . 它还包含SomeType单个实例。 Then, I made a QueryDBContext class which inherits DbContext . 然后,我做了一个QueryDBContext类,该类继承了DbContext

I have a Generate function which receives a string and creates a fully formed Query instance. 我有一个Generate函数,该函数接收一个字符串并创建一个完整的Query实例。 If I immediately send it to my View - it works fine. 如果我立即将其发送到我的View -可以正常工作。 But if I store it in my DB - only the primitive values are kept, and the reference types (both Lists<SomeType> and SomeType ) are null . 但是,如果将其存储在DB -仅保留原始值,并且引用类型( Lists<SomeType>SomeType )均为null

I believe the problem is that EF doesn't support reference types - or maybe I need something special for this case? 我认为问题在于EF不支持引用类型-或在这种情况下我需要特殊的东西吗?
Here's Query 这是Query

public class Query
{
    [Key]
    public int id { get; set; }

    public SomeType Base { get; set; }
    public List<SomeType> Derived { get; set; }
    //more of these

    public string SmallGraphImage { get; set; }
    public string MediumGraphImage { get; set; }
    public string LargeGraphImage { get; set; }
}
public class QueriesDBContext : DbContext
{
    public DbSet<Query> Queries { get; set; }
}

Here's SomeType 这是SomeType

public class SomeType
{
    [Key]
    public int id { get; set; }
    public string ExpandedOutForm { get; set; }
    public string ExpandedInForm { get; set; }
    //more strings
}


Note: The database works fine for primitives. 注意:该数据库适用于原语。 For developing purposes, I made a Controller which deletes & rebuilds the database for each modification. 出于开发目的,我制作了一个Controller ,该Controller针对每次修改删除并重建数据库。 I also tried replacing List with IList . 我也尝试用IList替换List

If EF doesn't support reference types, what should I do? 如果EF不支持引用类型,该怎么办? Will it work on structs ? 可以在structs吗? How can I store Lists inside a database entry? 如何将Lists存储在数据库条目中? (Yeah, I could store it in another table with its ID - but I believe EF has a more elegant solution for this) (是的,我可以将其存储在具有其ID的另一个表中-但我相信EF为此提供了更优雅的解决方案)

I believe the problem is that EF doesn't support reference types 我认为问题在于EF不支持引用类型

The Entity Framework does support reference types. 实体框架确实支持引用类型。 With the default configuration those will be mapped to a seperate database table. 使用默认配置,这些将被映射到单独的数据库表。 In your case, a Query_id column will be added to the table 'SomeTypes'. 在您的情况下,Query_id列将添加到表“ SomeTypes”中。 The Entity Framework will use those to create SQL Joins when loading data. 加载数据时,实体框架将使用这些实体来创建SQL连接。

The reason why your properties are showing as NULL has nothing to do with this. 您的属性显示为NULL的原因与此无关。 It has to do with how the Entity Framework loads data. 它与实体框架如何加载数据有关。 By default, EF will not load a whole object graph from the start. 默认情况下,EF不会从一开始就加载整个对象图。 This would mean that if your SomeType references another class which references another... and you would load the whole database in one call. 这意味着如果您的SomeType引用了另一个引用了另一个类的类,则您将在一个调用中加载整个数据库。

You have two options: 您有两种选择:

  • Explicitly loading the references . 显式加载参考 You tell the Entity Framework which properties you are going to use in advance and it will load them in one call from the database. 您事先告诉实体框架要使用哪些属性,它将在一次数据库调用中将其加载。

    Query c = ctx.Queries .Include(x => x.Derived) .Include(x => x.Base).First(); 查询c = ctx.Queries .Include(x => x.Derived).Include(x => x.Base).First();

Here you use the Include method to tell the Entity Framework to load both your Derived collection as your Base property. 在这里,您可以使用Include方法来告诉实体框架将Derived集合都加载为Base属性。

  • Use lazy loading. 使用延迟加载。 This means that the Entity Framework will load your property when it's needed. 这意味着实体框架将在需要时加载您的属性。 For this to work, EF creates a proxy class that wraps your class and will execute the database calls just in time. 为此,EF创建了一个代理类来包装您的类,并将及时执行数据库调用。

    For this to work, you will need to declare your public SomeType Base { get; set; } 为此,您需要声明您的public SomeType Base { get; set; } public SomeType Base { get; set; } public SomeType Base { get; set; } as virtual so EF can create a proxy and intercept those calls. public SomeType Base { get; set; }设为虚拟,因此EF可以创建代理并拦截这些调用。

The only reason you where not seeing your data, is because it wasn't loaded from the database. 您看不到数据的唯一原因是未从数据库中加载数据。

I believe the problem is that EF doesn't support reference types 我认为问题在于EF不支持引用类型

EF supports reference types - they're essentially mapped to other tables. EF支持引用类型-它们实际上已映射到其他表。

(Yeah, I could store it in another table with its ID - but I believe EF has a more elegant solution for this) (是的,我可以将其存储在具有其ID的另一个表中-但我相信EF为此提供了更优雅的解决方案)

Actually that'e exactly how EF handles 1-many relationships by default. 实际上,这正是 EF默认情况下处理多个关系的方式。 How are you intending to store those in a single table? 您打算如何将它们存储在单个表中?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM