Array
(
)

ComboBox da DEVEXPRESS e a chave estrangeira

Plinio Costa
   - 07 set 2015

Prezados, tenho o seguinte relacionamento entre as classes:

Classe UF:
#Código

using System.Collections;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;


namespace Exodo.Dominio
{
    public class Uf
    {
        [Required(ErrorMessage="Id da UF é obrigatório")]
        [Key]
        [Display(Name="Id")]
        public int IdUf { get; set; }
        
        [Required(ErrorMessage="Campo obrigatório")]
        [StringLength(100, ErrorMessage="Tamanho Maximo para o campo nome da UF: 100 caracteres")]
        [Display(Name="Descrição")]
        public string nmuf { get; set; }

        [Required(ErrorMessage="Campo obrigatório")]
        [StringLength(2, ErrorMessage="Tamanho do campo sigla: 2 caracteres")]
        [Display(Name="Sigla")]
        public string sguf { get; set; }

        public virtual IEnumerable<EmpresaConveniada> empresasConveniadas { get; set; }
        public virtual IEnumerable<Usuario> usuarios { get; set; }


    }
}



Classe EmpresaConveniada:
#Código
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;

namespace Exodo.Dominio
{

   public class EmpresaConveniada
    {
       [Required]
       [Key]
        public int idEmpresaConveniada { get; set; }

       [Required(ErrorMessage="Informe o nome do convênio")]
       [StringLength(150, ErrorMessage="Nome do convênio possui limite de 150 caracteres")]
       [Display(Name="Convênio")]
        public string nmconvenio { get; set; }

       [Required(ErrorMessage="Informe a Razão Social da Empresa Conveniada")]
       [StringLength(150, ErrorMessage="Razão Social da Empresa Conveniada Possui Limite de 150 Caracteres")]
       [Display(Name = "Razão Social")]
       public string rzsocial { get; set; }

       [Required(ErrorMessage="Informe o Nome Fantasia da Empresa Conveniada")]
       [StringLength(100, ErrorMessage="Nome Fantasia Possui Limite de 100 Caracteres")]
       [Display(Name = "Nome Fantasia")]
       public string nmfantasia { get; set; }

       [Required(ErrorMessage="Informe o C.N.P.J. da Empresa Conveniada")]
       [StringLength(20, ErrorMessage="CNPJ Possui Limite de 20 Caracteres")]
       [Display(Name = "C.N.P.J.")]
       public string nucnpj { get; set; }

       [Required(ErrorMessage="Informe a Inscrição Estadual da Empresa Conveniada")]
       [StringLength(20, ErrorMessage = "O campo Inscrição Estadual possui o limite de 20 caracteres")]
       [Display(Name = "Inscrição Estadual")]
       public string nuinscestadual { get; set; }

       [StringLength(15, ErrorMessage="Inscrição Municipal da Empresa Conveniada Possui Limite de 15 Caracteres")]
       [Display(Name = "Inscrição Muncipal")]
        public string nuinscmunicipal { get; set; }

       [Display(Name = "Endereço")]
       [StringLength(200, ErrorMessage = "O campo endereço possui o limite de 200 caracteres")]
       [Required(ErrorMessage = "Endereço do estabelecimento é obrigatório")]
       public string dsendereco { get; set; }

       [Display(Name = "Número")]
       [StringLength(10, ErrorMessage = "O campo número do endereço possui limite de 10 caracteres")]
       [Required(ErrorMessage = "O número do endereço é obrigatório")]
       public string nuendereco { get; set; }

       [Display(Name = "Complemento")]
       [StringLength(10, ErrorMessage="O campo Complemento possui limite de 10 caracteres")]
       public string dscomplemento { get; set; }

       [Display(Name = "CEP")]
       [StringLength(12, ErrorMessage = "O campo CEP possui limite de 12 caracteres")]
       [Required(ErrorMessage = "O CEP é obrigatório")]
       public string nucep { get; set; }

       [Display(Name = "Bairro")]
       [StringLength(120, ErrorMessage = "O campo Bairro possui limite de 120 caracteres")]
       [Required(ErrorMessage = "O Bairro é obrigatório")]
       public string nmbairro { get; set; }

       [Display(Name = "Cidade")]
       [StringLength(120, ErrorMessage = "O campo Cidade possui limite de 120 caracteres")]
       [Required(ErrorMessage = "Cidade é obrigatório")]
       public string nmcidade { get; set; }

       [Display(Name = "Fone")]
       [StringLength(15, ErrorMessage = "O campo Fone da Empresa Conveniada possui o limite de 15 caracteres")]
       public string nufone { get; set; }

       [Display(Name = "Celular")]
       [StringLength(15, ErrorMessage = "O campo Celular da Empresa Conveniada possui o limite de 15 caracteres")]
       public string nucelular { get; set; }

       [Display(Name = "e-mail")]
       [StringLength(150, ErrorMessage = "O campo e-mail da Empresa Conveniada possui o limite de 150 caracteres")]
       public string email { get; set; }

       [Display(Name = "Observação")]
       [StringLength(300, ErrorMessage = "O Campo Observação possui limite de 300 caracteres")]
       public string dsobservacao { get; set; }

       [Display(Name = "Data Cadastro")]
       [DataType(DataType.Date)]
       [DisplayFormat(DataFormatString = "{0:dd/MM/yyyy}")]
       public DateTime dtCadastro { get; set; }



       [Display(Name = "Nome Contato")]
       [StringLength(20, ErrorMessage = "O campo Nome Contato possui o limite de 20 caracteres")]
       [Required(ErrorMessage = "Nome do Contato é obrigatório")]
       public string nmcontato { get; set; }

       [Display(Name = "Fone Contato")]
       [StringLength(15, ErrorMessage = "O campo Fone do Contato possui o limite de 15 caracteres")]
       [Required(ErrorMessage = "Fone do Contato é obrigatório")]
       public string nufonecontato { get; set; }

       [Display(Name = "Celular Contato")]
       [StringLength(15, ErrorMessage = "O campo Celular do Contato possui o limite de 15 caracteres")]
       [Required(ErrorMessage = "Número do Celular do Contato é obrigatório")]
       public string nucelularcontato { get; set; }

       [Display(Name = "e-mail Contato")]
       [StringLength(150, ErrorMessage = "O campo e-mail do Contato possui o limite de 150 caracteres")]
       [Required(ErrorMessage = "O campo e-mail do contato é obrigatório")]
       public string emailcontato { get; set; }
       
       [Display(Name="Data Inclusão")]
       [DataType(DataType.Date)]
       [DisplayFormat(DataFormatString = "{0:dd.MM.yyyy}")] 
       public DateTime dtinclusao { get; set; }

       [Display(Name="Data Alteração")]
       [DataType(DataType.Date)]
       [DisplayFormat(DataFormatString = "{0:dd.MM.yyyy}")]
       public DateTime dtalteracao { get; set; }

       [Display(Name="Usuário Inclusão")]
       public string usuinclusao { get; set; }

       [Display(Name="Usuário Alteração")]
       public string usualteracao { get; set; }

       [Display(Name = "U.F.")]
       public int idUF { get; set; }

       public virtual Uf Uf { get; set; }







       
    }
}


Classe UFRepositorio:
#Código
using System.Collections.Generic;
using Exodo.Dominio;
using System.Linq;
using System.Data.Linq;
using System.Diagnostics;
using System.Collections;


namespace Exodo.Repositorio
{
    public class UfRepositorio : IRepositorio<Uf>
    {

        private  Contexto contexto;

        public UfRepositorio()
        {
            contexto = new Contexto();
        }


        public void salvar(Uf entidade)
        {
            if (entidade.IdUf > 0)
            {
                var UfAlterar = contexto.Ufs.First(x => x.IdUf == entidade.IdUf);
                UfAlterar.nmuf = entidade.nmuf;
                UfAlterar.sguf = entidade.sguf;
            }
            else
            {
                contexto.Ufs.Add(entidade);
            }

            contexto.SaveChanges();
        }

        public void excluir(Uf entidade)
        {
            if (entidade.IdUf > 0)
            {
                var excluir = contexto.Ufs.First(x => x.IdUf == entidade.IdUf);
                contexto.Set<Uf>().Remove(excluir);
                contexto.SaveChanges();
            }

        }

        public Uf porId(int id)
        {
            return contexto.Ufs.First(x => x.IdUf == id);
        }

        public IEnumerable<Uf> listarTodos()
        {
            return contexto.Ufs.ToList();
        }

        public List<Uf> listarSiglas()
        {
            return contexto.Ufs.ToList();
        }


        public static IEnumerable getUnidadesFederativas()
        {
            Contexto meuContexto = new Exodo.Repositorio.Contexto();

             var qry = from uf in meuContexto.Ufs
                 select new {
                             IdUf = uf.IdUf,
                             nmuf = uf.nmuf
                            };

             return qry.ToList();


        }





    }

}


#Código
using System.Data.Entity;
using System.Collections.Generic;
using System.Linq;
using Exodo.Dominio;


namespace Exodo.Repositorio
{
    public class EmpresaConveniadaRepositorio:IRepositorio<EmpresaConveniada>
    {

        private readonly Contexto contexto;

        public EmpresaConveniadaRepositorio()
        {
         contexto = new Contexto();
        }


        public void salvar(EmpresaConveniada entidade)
        {
            if (entidade.idEmpresaConveniada > 0)
            {
                var convenioAlterar = contexto.Conveniadas.First(x => x.idEmpresaConveniada == entidade.idEmpresaConveniada);
                convenioAlterar.nmconvenio      = entidade.nmconvenio;
                convenioAlterar.rzsocial        = entidade.rzsocial;
                convenioAlterar.nmfantasia      = entidade.nmfantasia;
                convenioAlterar.nucnpj          = entidade.nucnpj;
                convenioAlterar.nuinscestadual  = entidade.nuinscestadual;
                convenioAlterar.nuinscmunicipal = entidade.nuinscmunicipal;
                convenioAlterar.dsendereco      = entidade.dsendereco;
                convenioAlterar.nuendereco      = entidade.nuendereco;
                convenioAlterar.dscomplemento   = entidade.dscomplemento;
                convenioAlterar.nucep           = entidade.nucep;
                convenioAlterar.nmbairro        = entidade.nmbairro;
                convenioAlterar.nmcidade        = entidade.nmcidade;
                convenioAlterar.nufone          = entidade.nufone;
                convenioAlterar.nucelular       = entidade.nucelular;
                convenioAlterar.email           = entidade.email;
                convenioAlterar.nmcontato       = entidade.nmcontato;
                convenioAlterar.nufonecontato   = entidade.nufonecontato;
                convenioAlterar.nucelularcontato = entidade.nucelularcontato;
                convenioAlterar.emailcontato    = entidade.emailcontato;
                convenioAlterar.dsobservacao    = entidade.dsobservacao;
                convenioAlterar.dtCadastro      = entidade.dtCadastro;
                convenioAlterar.usuinclusao     = entidade.usuinclusao;
                convenioAlterar.usualteracao    = entidade.usualteracao;
                convenioAlterar.idUF            = entidade.idUF;
            }

            else
            {
                contexto.Conveniadas.Add(entidade);            
            }

            contexto.SaveChanges();
        }


        public void excluir(EmpresaConveniada entidade)
        {
            if(entidade.idEmpresaConveniada > 0)
            {
             var convenioExcluir = contexto.Conveniadas.First(x => x.idEmpresaConveniada == entidade.idEmpresaConveniada);
             contexto.Set<EmpresaConveniada>().Remove(convenioExcluir);
             contexto.SaveChanges();
            }
        }

        public EmpresaConveniada porId(int id)
        {
          return contexto.Conveniadas.First(x => x.idEmpresaConveniada == id);
        }

        public IEnumerable<EmpresaConveniada> listarTodos()
        {
         return contexto.Conveniadas.ToList();
        }
    }
}





#Código
using System;
using System.Linq;
using System.Web.Mvc;
using DevExpress.Web.Mvc;

using Exodo.Repositorio;
using Exodo.Dominio;


namespace Exodo.Controllers
{
    [Authorize]
    public class EmpresaConveniadaController : Controller
    {
       
        public readonly EmpresaConveniadaAplicacao appConvenio;
        public readonly UfAplicacao appUf;
        

        public EmpresaConveniadaController()
        {
         appConvenio = EmpresaConveniadaConstrutor.EmpConvAplicacao();
         appUf = UfAplicacaoContrutor.UfAplicacaoEF();
        }



        [HttpGet]
        public ActionResult Index()
        {
            var listaEmpresaConveniada = appConvenio.listarTodos();

            return View(listaEmpresaConveniada);
        }

        [HttpPost]
        public ActionResult Index(string idUF)
        {

            return View();
        }



        [HttpGet]
        public ActionResult Adicionar()
        {
          EmpresaConveniada empConv = new EmpresaConveniada(); 

          return View("Adicionar", empConv);
        }


        [HttpPost]
        [ValidateAntiForgeryToken]
        public ActionResult Adicionar(EmpresaConveniada empConv)
        {
           if (Exodo.Rotinas.Funcoes.IsCnpj(empConv.nucnpj) == false)
            {
                ModelState.AddModelError("CNPJ", "CNPJ Informado Inválido.");
            }

           if (ModelState.IsValid)
            {
                appConvenio.salvar(empConv);
                return RedirectToAction("Index");
            }

            return View(empConv);
        }


        [HttpGet] 
        public ActionResult Editar(int id)
        {
            var conv = appConvenio.porId(id);
            if (conv == null)
                return HttpNotFound();

            return View("Adicionar", conv);
        }


        [HttpPost]
        public ActionResult Editar(EmpresaConveniada empConv)
        {

           if (ModelState.IsValid)
            {
                appConvenio.salvar(empConv);
                return RedirectToAction("Index");
            }

            return View("Adicionar",empConv);

        }


        [HttpGet]
        public ActionResult Excluir(int id)
        {
            var conv = appConvenio.porId(id);
            if (conv == null)
                return HttpNotFound();
            return View(conv);
        }

        [HttpPost]
        [ActionName("Excluir")]
        public ActionResult ExcluirConfirmado(int id)
        {
            if (ModelState.IsValid)
            {
                var uf = appConvenio.porId(id);
                appConvenio.excluir(uf);
                return RedirectToAction("Index");
            }
            return View();
        }


        [ValidateInput(false)]
        public ActionResult grdParcial()
        {
            var model = appConvenio.listarTodos();
            return PartialView("_grdParcial", model.ToList());
        }





/*
        Exodo.Repositorio.Contexto db = new Exodo.Repositorio.Contexto();

        [ValidateInput(false)]
        public ActionResult grdParcial()
        {
            var model = db.Conveniadas;
            return PartialView("_grdParcial", model.ToList());
        }

        [HttpPost, ValidateInput(false)]
        public ActionResult grdParcialAddNew([ModelBinder(typeof(DevExpressEditorsBinder))] Exodo.Dominio.EmpresaConveniada item)
        {
            var model = db.Conveniadas;
            if (ModelState.IsValid)
            {
                try
                {
                    model.Add(item);
                    db.SaveChanges();
                }
                catch (Exception e)
                {
                    ViewData["EditError"] = e.Message;
                }
            }
            else
                ViewData["EditError"] = "Please, correct all errors.";
            return PartialView("_grdParcial", model.ToList());
        }

        [HttpPost, ValidateInput(false)]
        public ActionResult grdParcialUpdate([ModelBinder(typeof(DevExpressEditorsBinder))] Exodo.Dominio.EmpresaConveniada item)
        {
            var model = db.Conveniadas;
            if (ModelState.IsValid)
            {
                try
                {
                    var modelItem = model.FirstOrDefault(it => it.idEmpresaConveniada == item.idEmpresaConveniada);
                    if (modelItem != null)
                    {
                        this.UpdateModel(modelItem);
                        db.SaveChanges();
                    }
                }
                catch (Exception e)
                {
                    ViewData["EditError"] = e.Message;
                }
            }
            else
                ViewData["EditError"] = "Please, correct all errors.";
            return PartialView("_grdParcial", model.ToList());
        }
        [HttpPost, ValidateInput(false)]
        public ActionResult grdParcialDelete(System.Int32 idEmpresaConveniada)
        {
            var model = db.Conveniadas;
            if (idEmpresaConveniada >= 0)
            {
                try
                {
                    var item = model.FirstOrDefault(it => it.idEmpresaConveniada == idEmpresaConveniada);
                    if (item != null)
                        model.Remove(item);
                    db.SaveChanges();
                }
                catch (Exception e)
                {
                    ViewData["EditError"] = e.Message;
                }
            }
            return PartialView("_grdParcial", model.ToList());
        }
 * 
 * 
 * 
 */
 

    }
}



Minha View:
#Código
@model Exodo.Dominio.EmpresaConveniada
 
@{
    ViewBag.Title = "Adicionar";
    Layout = "~/Views/Shared/_Layout.cshtml";
}
 
@using (Html.BeginForm()) 
{
 
    @Html.AntiForgeryToken()
    @Html.ValidationSummary(true)
 
    <br />
    <br />
    <br />
    <br />
    <br />
    
    <br />
    <br />
    <br />
 
    @Html.HiddenFor(model => model.idEmpresaConveniada);
         
    <fieldset>
        <legend>Informações Básicas</legend>
 
    <table>
 
        <tr>
 
            <td>
               @Html.LabelFor(model => model.nmconvenio)     
            </td>
 
            <td>
              @Html.LabelFor(model => model.rzsocial)
            </td>
 
            <td>
               @Html.LabelFor(model => model.nmfantasia)
            </td>
 
        </tr>
 
        <tr>
 
        <td>
          @Html.EditorFor(m => m.nmconvenio)
        </td>
 
        <td>
          @Html.EditorFor(m => m.rzsocial)
        </td>
 
        <td>
          @Html.EditorFor(m => m.nmfantasia)
        </td>
 
 
        </tr>
 
        <tr>
           
          <td>
            @Html.LabelFor(model => model.nucnpj)
          </td>    
 
          <td>
            @Html.LabelFor(model => model.nuinscestadual)
          </td>    
 
          <td>
            @Html.LabelFor(model => model.nuinscmunicipal)
          </td>    
 
 
 
        </tr>
 
        <tr>
             
         <td>
           @Html.EditorFor(m => m.nucnpj)
         </td>
 
         <td>
            @Html.EditorFor(m => m.nuinscestadual)
         </td>
 
         <td>
            @Html.EditorFor(m => m.nuinscmunicipal)
         </td>
 
 
        </tr>
 
 
        <tr>
 
            <td>
               @Html.LabelFor(model => model.nufone)
            </td>
 
            <td>
               @Html.LabelFor(model => model.nucelular)
            </td>
 
            <td>
               @Html.LabelFor(model => model.email)
            </td>
 
        </tr>
 
        <tr>
 
         <td>
            @Html.EditorFor(m => m.nufone)
         </td>
 
         <td>
           @Html.EditorFor(m => m.nucelular)
         </td>
 
         <td>
           @Html.EditorFor(m => m.email)
         </td>
 
 
 
        </tr>
 
 
     </table>
 
    </fieldset>
 
     
   <fieldset>
    <legend>Endereço</legend>
     
    <table>
 
        <tr>
 
            <td>
               @Html.LabelFor(model => model.nucep)
            </td>
 
        </tr>
 
 
 
 
        <tr>
         <td>
           @Html.EditorFor(m => m.nucep)
         </td>
 
 
        </tr>
 
 
        <tr>
 
            <td>
                @Html.LabelFor(model => model.dsendereco)
            </td>
 
            <td>
              @Html.LabelFor(model => model.nuendereco)
            </td>
 
            <td>
              @Html.LabelFor(model => model.dscomplemento)
            </td>
 
 
 
        </tr>
 
 
        <tr>
 
         <td>
           @Html.EditorFor(m => m.dsendereco)
         </td>
 
         <td>
           @Html.EditorFor(m => m.nuendereco)
         </td>
 
 
         <td>
           @Html.EditorFor(m => m.dscomplemento)
         </td>
 
 
 
        </tr>
 
        <tr>
 
            <td>
              @Html.LabelFor(model => model.nmbairro)
            </td>
 
            <td>
              @Html.LabelFor(model => model.nmcidade)
            </td>
 
            <td>
                UF:
            </td>
 
        </tr>
 
        <tr>
 
            <td>
              @Html.EditorFor(m => m.nmbairro)
            </td>
 
            <td>
              @Html.EditorFor(m => m.nmcidade)                
            </td>
 
            <td>

                @Html.DevExpress().ComboBox(
                            settings => {
                                settings.Name = "IDUF";
                                settings.ControlStyle.CssClass = "editor";
                                settings.Properties.IncrementalFilteringMode = IncrementalFilteringMode.StartsWith;
                                settings.Properties.DropDownStyle = DropDownStyle.DropDownList;                                
                                settings.Properties.TextField = "NMUF";
                                settings.Properties.ValueField = "IDUF";
                                settings.Properties.ValueType = typeof(int);
                                settings.Width = 120;
                            }
                        ).BindList(Exodo.Repositorio.UfRepositorio.getUnidadesFederativas()).GetHtml()
            </td>
 
 
        </tr>
 
    </table>
 
 
     <fieldset>
      <legend>Informações Sobre o Contato / Representante </legend>
 
        <table>
 
            <tr>
 
                <td>
                    @Html.LabelFor(model => model.nmcontato)
                </td>
 
                <td>
                    @Html.LabelFor(model => model.nufonecontato)
                </td>
 
                <td>
                    @Html.LabelFor(model => model.nucelularcontato)
                </td>
 
                <td>
                    @Html.LabelFor(model => model.emailcontato)
                </td>
 
 
 
 
            </tr>
 
 
            <tr>
 
                 <td>
                    @Html.EditorFor(m => m.nmcontato)
                 </td>
 
                 <td>
                   @Html.EditorFor(m => m.nufonecontato)
                 </td>
 
                 <td>
                    @Html.EditorFor(m => m.nucelularcontato)
                 </td>
 
 
                 <td>
                    @Html.EditorFor(m => m.emailcontato)
                 </td>
 
 
 
            </tr>
 
 
        </table>
 
 
       </fieldset>
 
    </fieldset>
 
    
  <table>

      <tr>
          <td>
             @Html.DevExpress().Button(settings =>
                {
                    settings.Name = "btnSalvar";
                    settings.Text = "Salvar Registro" ;
                    settings.UseSubmitBehavior = true;
                }).GetHtml()
          </td>
 
      </tr>
 
      <tr>
 
           <td>
            @Html.ActionLink("Retornar à Tela Anterior", "Index")
          </td>
     </tr>
 
 
  </table>
     
    
}


 
 
@section Scripts {
    @Scripts.Render("~/bundles/jqueryval")
}


Bom, o problema:
Uma única view para cadastrar e alterar registro. Se não fosse pela chave estrangeira, estava tudo certo.
Porém, como tenho essa chave estrangeira (relacionamento em que uma UF pode ter 1 ou vários empresasConveniadas) da forma como está, meu ComboBox não traz
o valor selecionado ao editar e também quando vai salvar, salva o valor igual a zero.