I am trying to get the Latest News from my database but I keep getting this error: The ObjectContext instance has been disposed and can no longer be used for operations that require a connection. the error happens on the NewsEntity.GetObject() method. I've tried adding the ToList, enabled LazyLoading, re-ordered the way I create the object sets. I have taken out the loading of the Author and Icon and that worked but I need them :) Thanks for any help.
Here is my NewsEntity class:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Web.Repository.Entity
{
public class NewsEntity : BaseEntity<News>
{
public int Id { get; set; }
public string Title { get; set; }
public string Summary { get; set; }
public string Content { get; set; }
public int Icon { get; set; }
public DateTime Posted { get; set; }
public int Author { get; set; }
public bool Deleted { get; set; }
public virtual MemberEntity AuthorEntity { get; set; }
public virtual IconEntity IconEntity { get; set; }
public override News GetObject()
{
return new News
{
Id = Id,
Title = Title,
Summary = Summary,
Content = Content,
IconId = Icon,
Icon = IconEntity.GetObject(),
Posted = Posted,
AuthorId = Author,
Author = AuthorEntity.GetObject(),
Deleted = Deleted
};
}
}
}
This is my NewsObject class (For data transfer):
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Web.Repository.Entity
{
public class News : BaseObject
{
public int Id { get; set; }
public string Title { get; set; }
public string Summary { get; set; }
public string Content { get; set; }
public int IconId { get; set; }
public DateTime Posted { get; set; }
public int AuthorId { get; set; }
public bool Deleted { get; set; }
public Member Author { get; set; }
public Icon Icon { get; set; }
}
}
This is my Database Context class:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data.Objects;
using Web.Repository.Entity;
namespace Web.Repository
{
public class WebModelContext : ObjectContext
{
private IObjectSet<MemberEntity> _members;
private IObjectSet<IconEntity> _icons;
private IObjectSet<NewsEntity> _news;
public WebModelContext()
: base("name=WebRepository", "WebRepository")
{
ContextOptions.LazyLoadingEnabled = true;
_members = CreateObjectSet<MemberEntity>();
_icons = CreateObjectSet<IconEntity>();
_news = CreateObjectSet<NewsEntity>();
}
public IObjectSet<MemberEntity> Members
{
get { return _members; }
}
public IObjectSet<IconEntity> Icons
{
get { return _icons; }
}
public IObjectSet<NewsEntity> News
{
get { return _news; }
}
}
}
This is my NewsRepository class:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Web.Repository.Entity;
namespace Web.Repository
{
public class NewsRepository : IDisposable
{
private WebModelContext _context;
private WebModelContext Context
{
get
{
if (_context == null)
_context = new WebModelContext();
return _context;
}
}
public NewsRepository() { }
public IEnumerable<News> GetLatestNews()
{
return Context.News.Where(news => !news.Deleted).OrderByDescending(news => news.Posted).Take(5).ToList().Select(news => news.GetObject());
}
#region Disposing
private bool disposed;
protected virtual void Dispose(bool disposing)
{
if (!this.disposed)
{
if (disposing && _context != null)
{
_context.Dispose();
}
}
this.disposed = true;
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
#endregion
}
}
This is my class to get the latest news:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using Web.Repository.Entity;
using Web.Repository;
namespace Web.Infrastructure
{
public static class NewsHelper
{
public static IEnumerable<News> GetLatestNews()
{
IEnumerable<News> news;
using (var repository = new NewsRepository())
{
news = repository.GetLatestNews();
}
return news;
}
}
}
This is my controller:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using Web.Repository.Entity;
using Web.Models;
using Web.Infrastructure;
namespace Web.Controllers
{
public class HomeController : BaseController
{
public ActionResult Index()
{
NewsListModel model = new NewsListModel { News = NewsHelper.GetLatestNews().ToList() };
return View(model);
}
}
}
and finally this is my model:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using Web.Repository.Entity;
namespace Web.Models
{
public class NewsListModel
{
public IEnumerable<News> News { get; set; }
}
}
I fixed this by ensuring the latest news was infact a list instead of a collection/iqueryable
Related
I have problem with wtih fluent validation not working on List.
I did it as it is in documentation ( https://docs.fluentvalidation.net/en/latest/collections.html)
But it doesn't work while on single validation of AddressForCreation it does work.
Link to whole project: https://github.com/KryspinTrawnik/CafeMVC
I have entity OrderForCreationVm which has list of AddressForCreationVm.
**Please note I shortened OrderForCreation for clear view
using AutoMapper;
using AutoMapper.Configuration.Annotations;
using CafeMVC.Application.Interfaces.Mapping;
using CafeMVC.Application.ViewModels.Customer;
using CafeMVC.Application.ViewModels.Products;
using FluentValidation;
using System;
using System.Collections.Generic;
using System.Linq;
namespace CafeMVC.Application.ViewModels.Orders
{
[AutoMap(typeof(CafeMVC.Domain.Model.Order))]
public class OrderForCreationVm : IMapFrom<CafeMVC.Domain.Mo..del.Order>
{
[Ignore]
public List<AddressForCreationVm> Addresses { get; set; }
public void Mapping(Profile profile)
{
profile.CreateMap<CafeMVC.Domain.Model.Order, OrderForCreationVm>().ReverseMap()
.ForMember(d => d.OrderedProductsDetails, s => s.MapFrom(opt => opt.Products));
}
}
public class OrderForCreationValidator : AbstractValidator<OrderForCreationVm>
{
public OrderForCreationValidator()
{
RuleFor(x => x.Id).NotNull();
RuleForEach(x => x.Addresses).SetValidator(new AddressForCreationValidator());
}
}
}
AddressForCreationVm;
using AutoMapper;
using CafeMVC.Application.Interfaces.Mapping;
using FluentValidation;
using System;
using System.Collections.Generic;
using System.Linq;
namespace CafeMVC.Application.ViewModels.Customer
{
public class AddressForCreationVm : IMapFrom<CafeMVC.Domain.Model.Address>
{
public int Id { get; set; }
public string BuildingNumber { get; set; }
public int FlatNumber { get; set; }
public string Street { get; set; }
public string City { get; set; }
public string ZipCode { get; set; }
public string Country { get; set; }
public int CustomerId { get; set; }
public int AddressTypeId { get; set; }
public List<AddressTypeVm> AllAddressTypes { get; set; }
public string Btn { get; set; }
public void Mapping(Profile profile)
{
profile.CreateMap<AddressForCreationVm, CafeMVC.Domain.Model.Address>().ReverseMap();
}
}
public class AddressForCreationValidator : AbstractValidator<AddressForCreationVm>
{
public AddressForCreationValidator()
{
string[] availableZipcodes = new string[] { "LE1 ", "LE2", "LE3", "LE4" };
RuleFor(x => x.Id).NotNull();
RuleFor(x => x.AddressTypeId).NotNull();
RuleFor(x => x.BuildingNumber).NotEmpty().MaximumLength(255);
RuleFor(x => x.ZipCode).NotEmpty().Must(x => availableZipcodes.Any(prefix => x.StartsWith(prefix))).Length(7).When(x => x.AddressTypeId == 2);
RuleFor(x => x.City).Equal("Leicester").When(x => x.AddressTypeId == 2);
RuleFor(x => x.Country).MaximumLength(255).NotEmpty();
}
}
}
I made unit test for testing if RuleFor(x => x.ZipCode) is working:
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using CafeMVC.Application.ViewModels.Customer;
using CafeMVC.Application.ViewModels.Orders;
using CafeMVC.Domain.Model;
using FluentValidation;
using FluentValidation.TestHelper;
using Xunit;
namespace CafeMVC.Tests.FluentValidationTests
{
[Theory]
[InlineData("LE12 7EH")]
[InlineData("LE5 7EH")]
public void AddressForCreationValidatorUnderOrderShowErrorWIthWrongZipCode(string zipCode)
{
//Arrange
OrderForCreationValidator validator = new();
OrderForCreationVm order = new()
{
Addresses = new()
{
GetAddressForTests()
}
};
order.Addresses[0].ZipCode = zipCode;
//Act
var result = validator.TestValidate(order);
//Assert
result.ShouldHaveValidationErrorFor(x => x.Addresses[0].ZipCode);
}
}
}
Unfortunately test shows this:
I tried to change order validator to child rules like from documentation but it didn't work.
I specially wrot unit tests to check Addess validator itself and that's working properly.
I looked for similar issues on stackoverfolw but all of them are from older versions of Fluentvalidation or doesn't apply to my case.
I am getting a message: Error: Cannot convert from 'Intranet.Models.LoanOrderModification to Intranet.Models.LoanOrder on the line db.LoanOrders.Add(newLoan); from the code below. I created a new model in the class LoanOrders which I named LoanOrderModification , this class also has LoanOrder. What am I missing where the controller is looking for LoanOrder model and not LoanOrderModification model?
[HttpPost]
public ActionResult CreateModifiedLoanOrder(LoanOrderModification newLoanOrder, string submit)
{
try
{
if (ModelState.IsValid)
{
db.LoanOrders.Add(newLoanOrder);
db.SaveChanges();
return RedirectToAction("LoanOrders");
}
}
catch (Exception ex)
{
ModelState.AddModelError("", ex.Message);
}
return View();
}
Model:
namespace Intranet.Models
{
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.Web.Mvc;
public partial class LoanOrder
{
public int ID { get; set; }
public string Branch { get; set; }
public partial class LoanOrderModification
{
public int ID { get; set; }
public string Purpose { get; set; }
}
I created the new asp mvc core 2.0 angular template and added models and dtos which I want to map in the controller with Automapper. I included automapper 6.1.1 . When I navigate to http://localhost:61031/api/classes it gives me the exception Missing type map configuration or unsupported mapping. I read through many posts but are unable to find what is going on.
My code is as follows:
Overview of project
MODELS
Models.Classes.cs
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Linq;
using System.Threading.Tasks;
namespace WebApplication1.Models
{
public class Classes
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int Id { get; set; }
[Required]
[MaxLength(50)]
public string ClassName { get; set; }
[Required]
[Range(1, 50)]
public int MaxStudents { get; set; }
public ICollection<Students> Students { get; set; } = new List<Students>();
}
}
Models.Students.cs
using System;
namespace WebApplication1.Models
{
public class Students
{
public int Id { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public DateTime DateOfBirth { get; set; }
public Gender Gender { get; set; }
public Classes Classes { get; set; }
public int ClassId { get; set; }
}
}
Models.EdulyContext.cs
using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace WebApplication1.Models
{
public class EdulyContext : DbContext
{
public EdulyContext(DbContextOptions<EdulyContext> options) : base(options)
{
Database.Migrate();
}
public DbSet<Classes> Classes { get; set; }
public DbSet<Students> Students { get; set; }
}
}
DTOS
Dto.ClassesDtos.ClassesDto.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using WebApplication1.Models;
namespace WebApplication1.Dto.ClassesDtos
{
public class ClassesDto
{
public string ClassName { get; set; }
public int MaxStudents { get; set; }
public ICollection<Students> Students { get; set; } = new List<Students>();
}
}
Dto.StudentsDtos.StudentDto.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using WebApplication1.Models;
namespace WebApplication1.Dto.StudentsDtos
{
public class StudentsDto
{
public int Id { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public DateTime DateOfBirth { get; set; }
public Gender Gender { get; set; }
public Models.Classes Classes { get; set; }
public int ClassId { get; set; }
}
}
CONTROLLERS
Controllers.ClassesController.cs
using AutoMapper;
using Microsoft.AspNetCore.Mvc;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using WebApplication1.Dto.ClassesDtos;
using WebApplication1.Repositories.Interfaces;
namespace WebApplication1.Controllers
{
[Route("api/classes")]
public class ClassesController : Controller
{
private IClassesRepository _classesRepository;
public ClassesController(IClassesRepository classesRepository)
{
_classesRepository = classesRepository;
}
[HttpGet()]
public IActionResult GetClasses()
{
var classesEntities = _classesRepository.GetClasses();
var results = Mapper.Map<ClassesDto>(classesEntities);
return Ok(results);
}
}
}
Program.cs
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Logging;
namespace WebApplication1
{
public class Program
{
public static void Main(string[] args)
{
var host = BuildWebHost(args);
host.Run();
}
public static IWebHost BuildWebHost(string[] args)
{
return new WebHostBuilder()
.UseKestrel()
.UseContentRoot(Directory.GetCurrentDirectory())
.ConfigureAppConfiguration((builderContext, config) =>
{
IHostingEnvironment env = builderContext.HostingEnvironment;
})
.UseIISIntegration()
.UseStartup<Startup>()
.Build();
}
}
}
Startup.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.SpaServices.Webpack;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using WebApplication1.Models;
using WebApplication1.Dto;
using Microsoft.EntityFrameworkCore;
using WebApplication1.Repositories.Interfaces;
using WebApplication1.Repositories;
namespace WebApplication1
{
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc();
var connectionString = #"server=(localdb)\mssqllocaldb;Database=EdulyDbCore2;Trusted_Connection=True";
services.AddDbContext<EdulyContext>(o => o.UseSqlServer(connectionString));
services.AddScoped<IClassesRepository, ClassesRepository>();
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
app.UseWebpackDevMiddleware(new WebpackDevMiddlewareOptions
{
HotModuleReplacement = true
});
}
else
{
app.UseExceptionHandler("/Home/Error");
}
app.UseStaticFiles();
AutoMapper.Mapper.Initialize(cfg =>
{
cfg.CreateMap<Models.Classes, Dto.ClassesDtos.ClassesDto>();
cfg.CreateMap<Dto.ClassesDtos.ClassesDto, Models.Classes>();
cfg.CreateMap<Models.Students, Dto.StudentsDtos.StudentsDto>();
cfg.CreateMap<Dto.StudentsDtos.StudentsDto, Models.Students>();
});
app.UseMvc(routes =>
{
routes.MapRoute(
name: "default",
template: "{controller=Home}/{action=Index}/{id?}");
routes.MapSpaFallbackRoute(
name: "spa-fallback",
defaults: new { controller = "Home", action = "Index" });
});
}
}
}
In the startup I mapped both directions from classes to classesDto just to be certain. If anyone has any idea what I am doing wrong, help would be much aprreciated. Cheers!
After taking a small break I suddenly realized my mistake.
In classes controller the get return type should be an IEnumerable
so:
var results = Mapper.Map(classesEntities);
should become:
var results = Mapper.Map>(classesEntities);
I have the following model:
namespace Factura.Models
{
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Data.Entity.Spatial;
[Table("factura.marfa")]
public partial class marfa
{
[Key]
public int idmarfa { get; set; }
[StringLength(45)]
public string denumire { get; set; }
public int idfurnizor { get; set; }
}
}
And I have also a class that inherits DbContext:
namespace Factura.Models
{
using System;
using System.Data.Entity;
using System.ComponentModel.DataAnnotations.Schema;
using System.Linq;
public partial class FacturaContext : DbContext
{
public FacturaContext() : base("name=FacturaContext")
{
}
public virtual DbSet<marfa> marfas { get; set; }
[...]
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
[...]
}
}
}
In my controller I have the following code:
namespace Factura.Controllers
{
[Authorize]
public class CumparatorController : Controller
{
FacturaContext dbFactura = new FacturaContext();
[HttpGet]
public ActionResult Cumparaturi()
{
var marfas = dbFactura.marfas.ToList();
return View(marfas);
}
}
}
The problem I have is that dbFactura.marfas is null, it doesn't bring anything from Database even if the table is populated.
Can anyone help me with this?
Thank you!
Remove [Table("factura.marfa")] from marfa class and add the following in your OnModelCreating in FacturaContext
modelBuilder.Entity<marfa>().ToTable("factura_marfa"); //updated . with _
Create the migration & run
I'm using Entity Framework and MVC3, and my problem is that I can't scaffold Controllers if the class inherits from another Class.
Example:
This is Base Class
using System;
using System.Collections.Generic;
namespace CRMEntities
{
public partial class Company
{
public int Id { get; set; }
}
}
This is Lead Class (Child)
using System;
using System.Collections.Generic;
namespace CRMEntities
{
public partial class Lead : Company
{
public Lead()
{
this.Status = 1;
this.IsQualified = false;
}
public Nullable<short> Status { get; set; }
public Nullable<bool> IsQualified { get; set; }
}
}
When I tried to add controller below error comes...
Context Class COde
using System;
using System.Data.Entity;
using System.Data.Entity.Infrastructure;
namespace CRMEntities
{
public partial class CRMWebContainer : DbContext
{
public CRMWebContainer()
: base("name=CRMWebContainer")
{
}
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
throw new UnintentionalCodeFirstException();
}
public DbSet<Employee> Employees { get; set; }
public DbSet<Contact> Contacts { get; set; }
public DbSet<Product> Products { get; set; }
public DbSet<Location> Locations { get; set; }
public DbSet<Task> Tasks { get; set; }
public DbSet<EventInfo> EventInfoes { get; set; }
public DbSet<Opportunity> Opportunities { get; set; }
public DbSet<Comment> Comments { get; set; }
public DbSet<Document> Documents { get; set; }
public DbSet<LoginInformation> LoginInformations { get; set; }
public DbSet<CRMLog> CRMLogs { get; set; }
public DbSet<EntitySharing> EntitySharings { get; set; }
public DbSet<EntityFlagging> EntityFlaggings { get; set; }
public DbSet<EntityTagging> EntityTaggings { get; set; }
public DbSet<EntitySubscribing> EntitySubscribings { get; set; }
public DbSet<Compapny> Compapnies { get; set; }
}
}
The MVC AddController window check for a property DbSet of the ModelType you are adding.
You should do like vicentedealencar said, add to your CRMWebContainer:
[Obsolete("Design only", true)]
public DbSet<Lead> Leads { get; set; }
Remember that u should not use this property in your code (this is why the Obsolete Attribute), since the right way to get the Leads is using:
var leads = Companies.OfType< Lead >();