简体   繁体   English

MVC 5中的模型绑定问题

[英]Issue with the model binding in mvc 5

I'm having some issues when performing create operations with code-first. 使用代码优先执行创建操作时遇到一些问题。

I have these classes. 我有这些课。

[Table("Localidades")]
public class Localidad
{
    public Localidad() { 
    }

    public int LocalidadId { get; set; }

    [Required]
    [StringLength(150)]
    [Display(Name = "Nombre")]
    public string nombre { get; set; }

    public Provincia ProvinciaId { set; get; }
}

[Table("Provincias")]
public class Provincia
{
    public Provincia() { 
    }

    public int ProvinciaId { set; get; }

    [StringLength(150)]
    [Display(Name = "Nombre")]
    public string nombre { set; get; }
}

[Table("Domicilios")]
public class Domicilio
{
    public Domicilio() { 
    }

    public int DomicilioId { get; set; }

    [StringLength(150)]
    [Display(Name = "Calle")]
    public string calle { get; set; }

    [Display(Name = "Número")]
    public int numero { get; set; }

    [Display(Name = "Piso")]
    public int piso { get; set; }

    [Display(Name = "Departamento")]
    public char dpto { get; set; }

    [Display(Name = "Código Postal")]
    public int codigoPostal { get; set; }

    [Display(Name = "Localidad")]
    public Localidad LocalidadId { get; set; }
}

and

[Table("Personas")]
public  abstract class Persona
{
    public Persona() { 
    }

    [Key]
    public int ID { set; get; }

    public Domicilio DomicilioId { set; get; }

    [Required]
    [StringLength(150)]
    public string nombre { set; get; }

    [Required]
    [StringLength(40)]
    public string nroDocumento {get;set;}

    [Required]
    [StringLength(150)]
    public string apellido  {get;set;}

    public DateTime? fechaNacimiento {get;set;}

    public long telefonoFijo {get;set;}

    public long telefonoMovil {get;set;}

    [EmailAddress]
    public string email {get;set;}

    [Display(Name = "Sexo")]
    public char sexo {get;set;}

    [DataType(DataType.Date)]
    public DateTime? fechaAlta {get;set;}

    [DataType(DataType.Date)]
    public DateTime? fechaBaja { get;set;}
}

Localidad has a FK to Provincia, Domicilio has a FK to Localdiad and Persona has a FK to Localidades. Localidad对Provincia具有FK,Domicilio对Localdiad具有FK,Persona对Localidades具有FK。 So far so good the database schema is correct. 到目前为止,数据库架构是正确的。

When I try to create a new person my code is the following: (I got the id from a ddl that is working) 当我尝试创建一个新人时,我的代码如下:(我从正在运行的ddl中获得了ID)

var localidad = db.Localidades.Find(model.LocalidadId);
var domicilio = new Domicilio { calle = "estrada", dpto = 'a', LocalidadId = localidad };
var user = new ApplicationUser { UserName = model.nroDocumento.ToString(), Email = model.Email };
var paciente = new Paciente
{
    nombre = model.Nombre,
    apellido = model.Apellido,
    fechaAlta = DateTime.Now,
    nroDocumento = model.nroDocumento,
    DomicilioId = domicilio
};

With the id I got from the model (it is the correct id of the chosen Localidad), I retrieve the Localidad from the database and assign it to domicilio model. 使用从模型中获得的ID(它是所选Localidad的正确ID),我从数据库中检索Localidad并将其分配给domicilio模型。

The thing is that instead of linking the model to the appropriate Localidad in the database (using the FK) it creates a new register in the data base. 事实是,不是将模型链接到数据库中的相应Localidad(使用FK),而是在数据库中创建了一个新寄存器。

I know this is some misconception of the way code-first works so if anyone could point me in the right direction I'll be so grateful. 我知道这是对代码优先工作方式的误解,因此,如果有人能指出正确的方向,我将非常感激。

Ok so first of all in Entity Framework, you will use navigation properties rather than foreign keys. 好的,首先在Entity Framework中,您将使用导航属性而不是外键。 For performance and efficiency purposes, every single navigation property should lazyload since you don't want the EF to load every single navigation properties until you actually need them. 出于性能和效率的目的,每个导航属性都应延迟加载,因为您不希望EF实际需要它们时才加载每个导航属性。 You can achieve that by adding the keyword "virtual". 您可以通过添加关键字“虚拟”来实现。 In your Localidad: 在您的Localidad中:

public virtual Provincia Provincia { set; get; }

It is preferable to use the object name since this property is actually pointing at an instance of a Provincia object rather than being an ID. 最好使用对象名称,因为此属性实际上是指向Provincia对象的实例而不是ID。

In a one to many relationship like I am assuming the Provincia - localida relationship to be,you also need to include a collection in the one end. 在一对多关系中,例如我假设是Provincia-localida关系,您还需要在一端包含一个集合。

In your Provincia model: 在您的Provincia模型中:

public Provincia()
{
     this.Localidads = new HashSet<Localidad>();
}
public virtual ICollection<Localidad> Localidads { get; set; }

Here we're also adding a constructor to initialize the Localidads collection 在这里,我们还添加了一个构造函数来初始化Localidads集合

Now that we have set up a proper one-to-many relationship, update your database with a migration. 既然我们已经建立了正确的一对多关系,请通过迁移来更新数据库。

As for the way to add an object(Localidad) for exemple, you were about right on that part: create an object(Localidad) variable, fill it's scalar properties(non navigation). 至于添加一个对象(Localidad)的方式,您大概就是在这一部分:创建一个对象(Localidad)变量,填充其标量属性(非导航)。

To add a navigation property, you can either find it in your context or search it using the where method: 要添加导航属性,可以在上下文中找到它,也可以使用where方法搜索它:

Localidad.Provincia = db.Find(yourprovinciaID);

That's assuming you have the ID in hand. 假设您手头有ID。 If you don't you can search it using any scalar property: 如果不这样做,则可以使用任何标量属性进行搜索:

Localidad.Provincia = db.Provincias.Where(x=> x.attribute == attributevalue ).FirstOrDefault<Provincia>();

Once our object instance (Localidad in this exemple) has it's values filled, we can now add it to the context and save it to the database. 一旦对象实例(在此示例中为Localidad)填充了值,我们现在可以将其添加到上下文中并将其保存到数据库中。

context.Localidads.Add(Localidad);
context.SaveChanges();

The localidad will automatically be added to the collection in the corresponding provincia and Entity Framework will take care of foreign key matters for you. localidad将自动添加到相应省中的集合中,并且Entity Framework将为您处理外键问题。

What I just explained is basically how to make one to many relationships work. 我刚刚解释的基本上是如何使一对多关系起作用的。 If you want to use many-to-many or one-to-one relationships, I'd recommand looking up the Fluent API doc: msdn.microsoft.com/en-US/data/jj591620 . 如果要使用多对多或一对一关系,我建议您查询Fluent API文档: msdn.microsoft.com/en-US/data/jj591620

I am sorry if that is not clear to you and am willing to answer your questions. 很抱歉,如果您不清楚,并愿意回答您的问题。

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

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