使用MVP插入相关实体

本文关键字:实体 插入 MVP 使用 | 更新日期: 2023-09-27 18:28:00

我在C#应用程序中使用MVP模式和EF。在我的数据库设计中,"personas"answers"referencias"之间存在一对多的关系,每个"personas"可以有0个或多个"referencia"。

根据MVP模式,我有一个"Personas"模型,它在我的物理数据库中执行CRUD操作。我有一种方法可以像这样执行插入:

public void AgregaPersona(_Persona persona)
        {
               Persona per = new Persona()
                {
                    Nombres = persona.nombres,
                    ApellidoP = persona.apellidoP,
                    ApellidoM = persona.apellidoM,
                    FechaNacimiento = persona.fechaNacimiento,
                    Sexo = persona.sexo.ToString(),
                    EdoCivil = persona.edoCivil,
                    RFC = persona.RFC,
                    CURP = persona.CURP,
                    Domicilio = persona.domicilio,
                    CP = persona.codigoPostal,
                    Telefonos = persona.telefonos,
                    Celular = persona.celular,
                    Email = persona.email,
                    IDDel = persona.idDelegacion,
                    IDEmpresa = persona.idEmpresa
                };
                context.personas.AddObject(per);
                context.SaveChanges();
        }

问题是:如何将代码中的"referencias"插入关联起来?按照MVP规则,我必须为"referencias"创建一个模型,不是吗?我应该调用在"referencecias"模型中定义的插入方法吗?

使用MVP插入相关实体

您可以将它们添加到Referencia导航属性中。通过这种方式,它们也被插入到数据库中。

public void AgregaPersona(_Persona persona)
    {
           Persona per = new Persona()
            {
                Nombres = persona.nombres,
                ApellidoP = persona.apellidoP,
                ApellidoM = persona.apellidoM,
                FechaNacimiento = persona.fechaNacimiento,
                Sexo = persona.sexo.ToString(),
                EdoCivil = persona.edoCivil,
                RFC = persona.RFC,
                CURP = persona.CURP,
                Domicilio = persona.domicilio,
                CP = persona.codigoPostal,
                Telefonos = persona.telefonos,
                Celular = persona.celular,
                Email = persona.email,
                IDDel = persona.idDelegacion,
                IDEmpresa = persona.idEmpresa
            };
            Referencia ref1 = new Referencia();
            //populate related properties.
            per.Referencias.Add(ref1);
            context.personas.AddObject(per);
            context.SaveChanges();
    }

这是代码,然后我将解释:)

public class Persona
{
    public Persona()
    {
        //Make sure that Referencias is instantiated by default
        Referencias = new List<Referencia>();
    }
    public String Nombres {get; set;}
    //...The other properties of Persona
    public Int publicIDEmpresa {get; set;}
    //The virtual is here for lazy loading 
    public virtual ICollection<Referencia> Referencias {get; set;} 
}
public class Referencia
{
    public Int ReferenciaId {get; set;}
    public String Nombre {get; set;}
    //...Other properties of Referencia
}

让这些协同工作的代码:

    public void AgregaPersona(_Persona persona)
    {
           Persona per = new Persona()
            {
                Nombres = persona.nombres,
                ApellidoP = persona.apellidoP,
                ApellidoM = persona.apellidoM,
                FechaNacimiento = persona.fechaNacimiento,
                Sexo = persona.sexo.ToString(),
                EdoCivil = persona.edoCivil,
                RFC = persona.RFC,
                CURP = persona.CURP,
                Domicilio = persona.domicilio,
                CP = persona.codigoPostal,
                Telefonos = persona.telefonos,
                Celular = persona.celular,
                Email = persona.email,
                IDDel = persona.idDelegacion,
                IDEmpresa = persona.idEmpresa
            };
            Referencia newRef = new Referencia
            {
                Nombre = referenciaNombre;
                //Fill the rest of the properties except ID (this should be auto)
            }
            per.Referencias.Add(newRef);
            context.personas.AddObject(per);
            context.SaveChanges();
    }

只要创建两个相互关联的独立对象(正如您所期望的那样),这就是您所需要做的全部工作。以下是我对这里发生的事情的最佳描述

创建ICollection<Referencia> Referencias时,所要做的就是在两个对象(PersonaReferencia)之间创建链接(关系)。这些对象仍然是单独的,只是通过该集合进行链接。

当您使用Referencia映射实际创建Persona时,您必须创建Persona,然后创建Referencia的单独对象,并通过将其添加到Persona的ICollection映射(Referencias)将其关联到Persona。当实际代码运行以将其持久化到数据库时,它会将其视为单独的插入,类似于以下伪代码:

BEGIN TRANSACTION
INSERT PERSONA
GET PERSONA ID
INSERT REFERENCIA USING NEW PERSONA ID(Repeat until all Referencias are inserted)
COMMIT TRANSACTION

现在,请记住我关于懒惰加载的注释。默认情况下,无论何时加载Persona,它都不会加载Referencias,直到您真正需要它。只有当您尝试访问此属性中的值时,它才会从数据库中加载这些对象。因此,更进一步强调,这些确实是两个独立的对象。

此外,如果需要,还可以创建双向映射。您只需添加另一个链接(关系),这次是从Referencia到其对应的Persona

public class Referencia
{
    public Int ReferenciaId {get; set;}
    public String Nombre {get; set;}
    //....Other properties of Referencia
    public virtual Persona Persona {get;set;}
}

请注意,属性名称与类名相同。这是一种约定,如果您通过将属性命名为其他名称而有所偏离,则需要在Persona中的Referencias对象上方添加一个属性。因此,英孚知道这是一种双向关系。因此,如果您决定将Referencia中的Persona属性命名为类似于PersonaRef的名称,那么您的代码看起来更像这样:

public class Persona
{
    public Persona()
    {
        //Make sure that Referencias is instantiated by default
        Referencias = new List<Referencia>();
    }
    public String Nombres {get; set;}
    //...The other properties of Persona
    public Int publicIDEmpresa {get; set;}
    //The virtual is here for lazy loading 
    [InverseProperty("PersonaRef")]
    public virtual ICollection<Referencia> Referencias {get; set;} 
}

希望这能让你更好地理解EF中的关系是如何运作的(这可以很好地转化为其他ORM)。因此,您可以获得所需的两个不同的模型,并可以使用关系映射属性在这两个模型之间进行遍历。

这是Scott Gu关于EF Code First的一篇非常好的文章,您可能会发现它对有帮助

如果我理解你。。。

在视图(IViewPersona)中,您可以使用Referencia属性,然后您可以构建一个新对象并插入它。

谨致问候。

免责声明:我不熟悉EF和MVP,只熟悉ORM。

您很可能需要实例化Referencia类的新实例,并可能将它们添加到Persona类的集合中。

在我的ActiveRecord/NHibernate堆栈中,以下是我的操作方式:

Persona per = new Persona(...); // as you do now
per.Referencias = new List<Referencia>();
per.Referencias.Add(new Referencia(...)); // same way you create Personas

希望能有所帮助。