我应该如何在 MVC3 中使用代码优先实体框架 (4.1) 声明外键关系? [英] How Should I Declare Foreign Key Relationships Using Code First Entity Framework (4.1) in MVC3?

查看:15
本文介绍了我应该如何在 MVC3 中使用代码优先实体框架 (4.1) 声明外键关系?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直在寻找有关如何使用代码优先 EF 4.1 声明外键关系和其他约束的资源,但运气不佳.基本上我在代码中构建数据模型并使用 MVC3 来查询该模型.一切都通过 MVC 工作,这很棒(向 Microsoft 致敬!)但现在我希望它不起作用,因为我需要有数据模型约束.

I have been searching for resources on how to declare foreign key relationships and other constraints using code first EF 4.1 without much luck. Basically I am building the data model in code and using MVC3 to query that model. Everything works via MVC which is great (kudos to Microsoft!) but now I want it NOT to work because I need to have data model constraints.

例如,我有一个 Order 对象,它有大量的外部对象(表)属性.现在我可以创建订单没问题,但无法添加外键或外部对象.MVC3 设置这个没问题.

For example, I have a Order object that has a ton of properties that are external objects (tables). Right now I can create an Order no problem, but without being able to add the foreign key or external objects. MVC3 sets this up no problem.

我意识到我可以在保存之前自己在控制器类中添加对象,但如果约束关系没有得到满足,我希望对 DbContext.SaveChanges() 的调用失败.

I realize that I could just add the objects myself in the controller class prior to save, but I would like the call to DbContext.SaveChanges() to fail if the constraint relationships have not been met.

新信息

所以,具体来说,我想要一个当我尝试时发生异常保存一个 Order 对象而不指定客户对象.这个如果我,这似乎不是行为只需按照描述组合对象在大多数 Code First EF 文档中.

So, specifically, I would like an exception to occur when I attempt to save an Order object without specifying a customer object. This does not seem to be the behavior if I just compose the objects as described in most Code First EF documentation.

最新代码:

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

    [ForeignKey( "Parent" )]
    public Patient Patient { get; set; }

    [ForeignKey("CertificationPeriod")]
    public CertificationPeriod CertificationPeriod { get; set; }

    [ForeignKey("Agency")]
    public Agency Agency { get; set; }

    [ForeignKey("Diagnosis")]
    public Diagnosis PrimaryDiagnosis { get; set; }

    [ForeignKey("OrderApprovalStatus")]
    public OrderApprovalStatus ApprovalStatus { get; set; }

    [ForeignKey("User")]
    public User User { get; set; }

    [ForeignKey("User")]
    public User Submitter { get; set; }

    public DateTime ApprovalDate { get; set; }
    public DateTime SubmittedDate { get; set; }
    public Boolean IsDeprecated { get; set; }
}

这是我现在在访问患者的 VS 生成视图时遇到的错误:

This is the error I get now when accessing the VS generated view for Patient:

错误信息

属性上的 ForeignKeyAttribute类型上的患者"'PhysicianPortal.Models.Order' 不是有效的.外键名称 'Parent'在依赖类型上找不到'PhysicianPortal.Models.Order'.这名称值应以逗号分隔外键属性名称列表.

The ForeignKeyAttribute on property 'Patient' on type 'PhysicianPortal.Models.Order' is not valid. The foreign key name 'Parent' was not found on the dependent type 'PhysicianPortal.Models.Order'. The Name value should be a comma separated list of foreign key property names.

问候,

圭多

推荐答案

如果您有一个 Order 类,请添加引用模型中另一个类的属性,例如 Customer 应该足以让 EF 知道那里有关系:

If you have an Order class, adding a property that references another class in your model, for instance Customer should be enough to let EF know there's a relationship in there:

public class Order
{
    public int ID { get; set; }

    // Some other properties

    // Foreign key to customer
    public virtual Customer Customer { get; set; }
}

你总是可以显式设置FK关系:

You can always set the FK relation explicitly:

public class Order
{
    public int ID { get; set; }

    // Some other properties

    // Foreign key to customer
    [ForeignKey("Customer")]
    public string CustomerID { get; set; }
    public virtual Customer Customer { get; set; }
}

ForeignKeyAttribute 构造函数接受一个字符串作为参数:如果你把它放在一个外键属性上,它表示关联导航属性的名称.如果你把它放在导航属性上,它代表关联外键的名称.

The ForeignKeyAttribute constructor takes a string as a parameter: if you place it on a foreign key property it represents the name of the associated navigation property. If you place it on the navigation property it represents the name of the associated foreign key.

这意味着,如果您将 ForeignKeyAttribute 放在 Customer 属性上的什么位置,该属性将在构造函数中采用 CustomerID:

What this means is, if you where to place the ForeignKeyAttribute on the Customer property, the attribute would take CustomerID in the constructor:

public string CustomerID { get; set; }
[ForeignKey("CustomerID")]
public virtual Customer Customer { get; set; }

<小时>

根据最新代码进行编辑由于这一行,您会收到该错误:


EDIT based on Latest Code You get that error because of this line:

[ForeignKey("Parent")]
public Patient Patient { get; set; }

EF 将寻找一个名为 Parent 的属性,将其用作外键执行器.你可以做两件事:

EF will look for a property called Parent to use it as the Foreign Key enforcer. You can do 2 things:

1) 删除 ForeignKeyAttribute 并将其替换为 RequiredAttribute 以将关系标记为必需:

1) Remove the ForeignKeyAttribute and replace it with the RequiredAttribute to mark the relation as required:

[Required]
public virtual Patient Patient { get; set; }

RequiredAttribute 修饰属性也有一个很好的副作用:数据库中的关系是用 ON DELETE CASCADE 创建的.

Decorating a property with the RequiredAttribute also has a nice side effect: The relation in the database is created with ON DELETE CASCADE.

我还建议将属性设为 virtual 以启用延迟加载.

I would also recommend making the property virtual to enable Lazy Loading.

2) 创建一个名为 Parent 的属性,用作外键.在这种情况下,调用它可能更有意义,例如 ParentID(您还需要更改 ForeignKeyAttribute 中的名称):

2) Create a property called Parent that will serve as a Foreign Key. In that case it probably makes more sense to call it for instance ParentID (you'll need to change the name in the ForeignKeyAttribute as well):

public int ParentID { get; set; }

根据我在这种情况下的经验,尽管采用相反的方式效果更好:

In my experience in this case though it works better to have it the other way around:

[ForeignKey("Patient")]
public int ParentID { get; set; }

public virtual Patient Patient { get; set; }

这篇关于我应该如何在 MVC3 中使用代码优先实体框架 (4.1) 声明外键关系?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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