I'm working with EF CodeFirst. My classes are:
public class Persona
{
public int Id { get; set; }
public string Nombre { get; set; }
public string ApellidoUno { get; set; }
public string ApellidoDos { get; set; }
public virtual ICollection<Telefono> Telefonos { get; set; }
}
public class Telefono
{
public virtual int Id { get; set; }
public virtual string Numero { get; set; }
public virtual int IdPersona { get; set; }
public virtual Persona Persona { get; set; }
}
public class ContactoContexto : DbContext
{
public ContactoContexto()
: base("EF_Model")
{ }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.Entity<Persona>().ToTable("Personas");
// ... more Fluent API code.....
modelBuilder.Entity<Persona>()
.HasMany(x => x.Telefonos)
.WithRequired(x => x.Persona)
.HasForeignKey(x => x.IdPersona);
}
public DbSet<Persona> Personas { get; set; }
public DbSet<Telefono> Telefonos { get; set; }
}
And when I try to select some data, I get the following error:
Error 1 No se encontró una implementación del modelo de consulta para el tipo de origen 'EF_Model.ContactoContexto'. 'Where' no encontrado. c:\users\jmolina\documents\visual studio 2013\Projects\prueba EF general\3. ModeloNEgocio\ModeloNegocio.cs 27 39 3. ModeloNegocio
My code to select is:
public class Intento
{
public static IEnumerable<Persona> buscarcontactos(string nombre)
{
ContactoContexto conCon = new ContactoContexto();
var personas = (from p in conCon where p.nombre == nombre select p);
return personas;
}
}
What is wrong in my code?
Thanks in advance.
Jeronimo
When you're doing a Linq query in your context, you need to start from a DbSet. You should also instantiate the DbContext in a using statement to ensure that it gets properly disposed when you're done.
using (var conCon = new ContactoContexto())
{
var personas = (from p in conCon.Personas where p.Nombre == nombre select p);
// you need to use ToList() to actually materialize the result from the database
return personas.ToList();
}
Related
I am creating ASP.Net MVC WebApi to share my data to bank. In this regard i have created an SQL View bit when i am testing my WebApi it is giving an 'System.OutOfMemoryException' error because i have more the 1 million record in SQL View.
My Code is given below:-
This is my controller
public class InvoiceController : ApiController
{
public IEnumerable<VBank_invoice> Get()
{
using (kmcEntities entities = new kmcEntities())
{
return entities.VBank_invoice.ToList();
}
}
public VBank_invoice Get(string consumer)
{
using (kmcEntities entities = new kmcEntities())
{
return entities.VBank_invoice.FirstOrDefault(e => e.consumer_no == consumer);
}
}
}
My SQL View Class
public partial class VBank_invoice
{
public int sno { get; set; }
public string consumer_no { get; set; }
public string consumer_name { get; set; }
public string consumer_address { get; set; }
public string billing_month { get; set; }
public Nullable<decimal> current_Charges { get; set; }
public Nullable<decimal> outstanding_Arrears { get; set; }
public Nullable<decimal> Arrears_15 { get; set; }
public Nullable<decimal> part_payment_arrears { get; set; }
public string billing_period_code { get; set; }
public string consumer_checkdigit { get; set; }
public Nullable<System.DateTime> due_date { get; set; }
}
This is my Model.Context.cs File
public partial class kmcEntities : DbContext
{
public kmcEntities()
: base("name=kmcEntities")
{
}
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
throw new UnintentionalCodeFirstException();
}
public virtual DbSet<VBank_invoice> VBank_invoice { get; set; }
}
I believe you need to be serialize object model using the select query.
public class InvoiceController : ApiController
{
public IEnumerable<VBank_invoice> Get()
{
using (kmcEntities entities = new kmcEntities())
{
return entities.VBank_invoice.select(m => new {
m.sno, m.consumer_no,m.consumer_name, m.consumer_address,
m.billing_month, m.current_Charges, m.outstanding_Arrears,
m.Arrears_15, m.part_payment_arrears, m.billing_period_code,
m.consumer_checkdigit, m.due_date }).ToList();
}
}
}
Why db.Countries() comes null in following scenario-
1. CityController
[Authorize]
public class CityController : Controller
{
private ApplicationDbContext db = new ApplicationDbContext("CP");
// GET: City/Create
public ActionResult Create()
{
ViewBag.CountryId = new SelectList(db.Countries.ToList(), "CountryId", "Name");
return View();
}
ApplicationDbContext
public class ApplicationDbContext : DbContext
{
public ApplicationDbContext(string nameOrConnectionString)
: base(nameOrConnectionString)
{
}
internal IDbSet<Country> Countries { get; set; }
...
}
Country is defined as-
[Table("Country")]
public class Country
{
#region Fields
private ICollection<City> _cities;
#endregion
#region Scalar Properties
public Guid CountryId { get; set; }
public string Name { get; set; }
public string CountryCode { get; set; }
#endregion
#region Navigation Properties
public virtual ICollection<City> Cities
{
get { return _cities ?? (_cities = new List<City>()); }
set { _cities = value; }
}
#endregion
}
City is defined as-
[Table("City")]
public class City
{
#region Fields
private ICollection<Location> _locations;
#endregion
#region Scalar Properties
public Guid CityId { get; set; }
public Guid CountryId { get; set; }
public string Name { get; set; }
public string CityCode { get; set; }
public string ZipCode { get; set; }
public Country Country { get; set; }
#endregion
#region Navigation Properties
public virtual ICollection<Location> Locations
{
get { return _locations ?? (_locations = new List<Location>()); }
set { _locations = value; }
}
#endregion
}
What could be the reason for not populating Country table records and returning countries to null?
After sparing few hours, I just noticed the Access-modifier of Countries properties which was internal. I made it Public and magic happened! It works though I don't have any explanation on WHY part of it.
public class ApplicationDbContext : DbContext
{
public ApplicationDbContext(string nameOrConnectionString)
: base(nameOrConnectionString)
{
}
//internal IDbSet<Country> Countries { get; set; }
public IDbSet<Country> Countries { get; set; }
public IDbSet<City> Cities { get; set; }
Thanks everyone.
I'm having a strange issue when I try to delete an entity Produto using my repository.
Generic Repository:
public class RepositoryBase<T> : IDisposable, IRepositoryBase<T> where T : ModelBase
{
/*Other Methods that work perfectly*/
public virtual int Delete(int id)
{
try
{
T entity = _dataContext.Set<T>().Find(id);
_dataContext.Set<T>().Remove(entity);
return _dataContext.SaveChanges();
}
catch(DbEntityValidationException ex)
{
}
}
}
Entity:
public class Produto : ModelBase
{
public virtual int? CodigoComercial { get; set; }
[Required]
[MaxLength(150)]
public virtual string Nome { get; set; }
[MaxLength(400)]
public virtual string Ingredientes { get; set; }
[Required]
public virtual CategoriaProduto Categoria { get; set; }
public Produto()
{
Categoria = new CategoriaProduto();
}
}
public class CategoriaProduto : ModelBase
{
[Required]
[MaxLength(150)]
public virtual string Nome { get; set; }
[MaxLength(400)]
public virtual string Descricao { get; set; }
public virtual CategoriaProduto CategoriaPai { get; set; }
public virtual IList<OpcaoIngrediente> Opcoes { get; set; }
public virtual CorCategoriaProdutoEnum Cor { get; set; }
public virtual bool Simples { get; set; }
[MaxLength(400)]
public string Imagem { get; set; }
public CategoriaProduto()
{
Opcoes = new List<OpcaoIngrediente>();
}
}
I found the way to catch the exception, that makes no sense, I try to Delete the Product, but It claims that the CategoriaProduto has the Name empty and It's required. as below:
SaborFit.Data.Model.CategoriaProduto failed validation
Nome : The field Nome is required.
I can't figure out the issue. If I try to delete the CategoriaProduto, all goes well.
I don't know why you are using Virtual property for most of fields, This cause to have lazy loading and obviously you'll encounter validation error on Any Operation where you call entire entity like .Find() operand. You must first decide what do you wanna do! Another solution that I don't prefer for you is disabling validation on save changes:
context.Configuration.ValidateOnSaveEnabled = false;
context.SaveChanges();
How do I populate a navigation property with specific value?
I have 3 models, Game, UserTeam, User, defined below. I have a razor view which uses the model IEnumerable. This view loops over the Games, and within that loop, loops over the UserTeams. So far, so good.
Within the UserTeam loop, I want to access the User properties, but they are null. How do I populate the User navigation property for each UserTeam object? Do I need a constructor with a parameter in the UserTeam model?
Models
public class Game
{
public Game()
{
UserTeams = new HashSet<UserTeam>();
}
public int Id { get; set; }
public int CreatorId { get; set; }
public string Name { get; set; }
public int CurrentOrderPosition { get; set; }
public virtual UserProfile Creator { get; set; }
public virtual ICollection<UserTeam> UserTeams { get; set; }
}
public class UserTeam
{
public UserTeam()
{
User = new UserProfile();
}
public int Id { get; set; }
public int UserId { get; set; }
public int GameId { get; set; }
public int OrderPosition { get; set; }
public virtual UserProfile User { get; set; }
public virtual Game Game { get; set; }
public virtual IList<UserTeam_Player> UserTeam_Players { get; set; }
}
public class UserProfile
{
[Key]
[DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
public int UserId { get; set; }
public string UserName { get; set; }
public string test { get; set; }
public UserProfile()
{
UserTeams = new HashSet<UserTeam>();
}
public virtual ICollection<UserTeam> UserTeams { get; set; }
[ForeignKey("CreatorId")]
public virtual ICollection<Game> Games { get; set; }
}
Loop in my Razor view (Model is IEnumerable)
#foreach (var item in Model) {
#foreach (var userteam in item.UserTeams) {
#Html.ActionLink("Join game as"+userteam.User.UserName, "JoinGame", new { gameid = item.Id, userid=userteam.UserId })
}
}
Method in my repository that returns the Games
public IEnumerable<Game> GetAllGames()
{
using (DataContext)
{
var gm = DataContext.Games.Include("UserTeams").ToList();
return gm;
}
}
You would need to include this in your repository method. If you are using eager loading then it would be something like
var gm = DataContext.Games
.Include(x => x.UserTeams)
.Include(x => x.UserTeams.Select(y => y.User))
.ToList();
I have not done this without using LINQ for my queries, but I assume it would be something like:
var gm = DataContext.Games.Include("UserTeams.User").ToList();
Hopefully this helps you out
Im having trouble linking my loaned items to my Library for each customer. It does it fine when it goes through the "AddToLibrary" method but when it comes to retreiving it, the medialibrary is empty and the query in the IEnumerable<Item> ItemsOnLoan method is returning null. This is a very basic ASP.NET MVC 4 application and im very new to this so its probably something silly ive missed out.
I just want to be able to add an item to the loaned items table, have the list of loaned items for each customer appear in their personal Library (defined in model) and then retreive the list of their items. Below is all the code and I am using a code first approach. Thank you :)
Model
public class Customer
{
public int Id { get; set; }
public string ForeName { get; set; }
public string SurName { get; set; }
public Address address { get; set; }
public string Email { get; set; }
public string Telephone { get; set; }
public string Mobile { get; set; }
public List<LoanedItem> Library { get; set; }
public Customer()
{
if (Library == null || Library.Count == 0)
{
Library = new List<LoanedItem>();
}
}
public IEnumerable<Item> ItemsOnLoan
{
get
{
var items = (from i in Library
where i.Customer.Id == this.Id
select i).OfType<item>();
return items;
}
}
}
Loaned Item model
public class LoanedItem
{
public int? Id { get; set; }
public Customer Customer { get; set; }
public MediaItem Item { get; set; }
}
ItemController --> adding to library method
public ActionResult AddToLibrary(int id)
{
Item libraryItem = db.Items.Find(id);
Customer c = db.Customers.Find(1);
LoanedItem newLoanGame = new LoanedItem()
{
Customer = c,
Item = libraryItem
};
db.LoanedItems.Add(newLoanGame);
db.SaveChanges();
return RedirectToAction("Index");
}
Customer Controller
public ActionResult ViewProfile(int id = 1)
{
Customer c = db.Customers.Find(id);
if (c == null)
{
return HttpNotFound();
}
return View(c);
}
public ActionResult GetLibraryItems(int id = 1)
{
var items = db.Customers.Find(id).ItemsOnLoan;
return View(items);
}
Context
public class LibraryContext : DbContext
{
public DbSet<Address> Addresses { get; set; }
public DbSet<Customer> Customers { get; set; }
public DbSet<LoanedItem> LoanedItems { get; set; }
public DbSet<Item> Items { get; set; }
public LibraryContext()
: base("LbContext")
{
}
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Configurations.Add(new CustomerConfiguration());
modelBuilder.Configurations.Add(new LoanedItemConfiguration());
modelBuilder.Entity<Item>();
modelBuilder.Entity<Address>();
base.OnModelCreating(modelBuilder);
}
}
Assuming that Proxy generation is enabled try this:
public class Customer
{
public int Id { get; set; }
public string ForeName { get; set; }
public string SurName { get; set; }
public Address address { get; set; }
public string Email { get; set; }
public string Telephone { get; set; }
public string Mobile { get; set; }
public virtual ICollection<LoanedItem> ItemsOnLoan { get; set; }
public Customer()
{
}
}
using this to acccess:
public ActionResult GetLibraryItems(int id = 1)
{
var customer = db.Customers.Find(id);
if (customer != null)
{
var items = customer.ItemsOnLoan;
return View(items);
}
//handle not found or throw an exception
throw new Exception();
}
follow this link for more information on Proxies and Lazy Loading.