Sharp Architecture inheritance problem - s#arp-architecture

my problem is with inheritance.
I have a Actor class
using System.Collections.Generic;
using SharpArch.Core;
using SharpArch.Core.DomainModel;
namespace ProTeria.NET.Common.Domain
{
public class Actor : Entity
{
public Actor()
{
Init();
}
private void Init()
{
Addresses = new List<Address>();
}
public virtual Account Account { get; set; }
public virtual string Number { get; set; }
public virtual string Telephone { get; set; }
public virtual string Fax { get; set; }
public virtual string Email { get; set; }
public virtual string IdNumber { get; set; }
public virtual CountryCode Country { get; set; }
public virtual IList<Address> Addresses { get; set; }
public virtual void AddAddress(Address address)
{
address.Actor = this;
Addresses.Add(address);
}
}
}
and also two derived classes,
using System.Collections.Generic;
using SharpArch.Core;
using SharpArch.Core.DomainModel;
namespace ProTeria.NET.Common.Domain
{
public class Company : Actor
{
private string _companyName;
protected Company()
{
Init();
}
public Company(string companyName)
: this()
{
Check.Require(!string.IsNullOrEmpty(companyName) && companyName.Trim() != string.Empty,
"Company name must be provided");
_companyName = companyName;
}
private void Init()
{
Employees = new List<Employee>();
}
public virtual Account Account { get; set; }
public virtual string EoriNumber { get; set; }
[DomainSignature]
public virtual string CompanyName
{
get { return _companyName; }
protected set { _companyName = value; }
}
public virtual CompanyNcts CompanyNcts {get;set;}
public virtual IList<Employee> Employees { get; set; }
public virtual void AddEmployee(Employee employee)
{
employee.Company = this;
Employees.Add(employee);
}
}
}
and
using SharpArch.Core;
using SharpArch.Core.DomainModel;
namespace ProTeria.NET.Common.Domain
{
public class Contact : Actor
{
private string _foreName;
protected Contact()
{
}
public Contact(string foreName)
: this()
{
Check.Require(!string.IsNullOrEmpty(foreName) && foreName.Trim() != string.Empty,
"Contact first name must be provided");
_foreName = foreName;
}
public virtual Account Account { get; set; }
[DomainSignature]
public virtual string ForeName
{
get { return _foreName; }
protected set { _foreName = value; }
}
public virtual string Surname { get; set; }
public virtual string Mobile { get; set; }
}
}
When I call
Actor actor = _actorRepository.Get(id);
it works fine. And I get the correct type of actor -> company or contact
The problem is when I embed the Actor class with another class as below.
using System;
using System.Collections.Generic;
using NHibernate.Validator.Constraints;
using SharpArch.Core;
using SharpArch.Core.DomainModel;
namespace ProTeria.NET.Common.Domain
{
public class Article : Entity
{
private string _number;
public Article(string number, Account account)
: this()
{
Check.Require(!string.IsNullOrEmpty(number)
&& number.Trim() != String.Empty,
"ArticleNumber must be provided");
Check.Require((account != null), "Account must be provided");
_account = account;
_number = number;
}
protected Article()
{
Init();
}
private void Init()
{
Descriptions = new List<ArticleDescription>();
UnitPrices = new List<ArticlePrice>();
}
private Account _account;
public virtual Account Account
{
get { return _account; }
set { _account = value; }
}
[DomainSignature]
[NotNull, NotEmpty]
public virtual string Number
{
get { return _number; }
protected set { _number = value; }
}
public virtual Actor Sender { get; set; }
public virtual CurrencyCode CurrencyCode { get; set; }
[NotNull]
public virtual LanguageCode LanguageCode { get; set; }
public virtual ArticleNcts ArticleNcts { get; set; }
public virtual ArticleDe ArticleDe { get; set; }
public virtual ArticleSe ArticleSe { get; set; }
public virtual ArticleNo ArticleNo { get; set; }
public virtual CountryCode CountryCode { get; set; }
public virtual HsCode HsCode { get; set; }
public virtual double GrossWeight { get; set; }
public virtual double NetWeight { get; set; }
public virtual string ExportCode { get; set; }
public virtual string ImportCode { get; set; }
public virtual string TaricCode { get; set; }
public virtual IList<ArticleDescription> Descriptions { get; set; }
public virtual IList<ArticlePrice> UnitPrices { get; set; }
public virtual void AddArticleDescription(ArticleDescription articleDescription)
{
Descriptions.Add(articleDescription);
}
public virtual void AddArticlePrice(ArticlePrice articlePrice)
{
UnitPrices.Add(articlePrice);
}
}
}
Then if I call
Article article = _articleRepository.Get(articleId);
article.Sender won't be mapped correctly, it is in its base type, not the derived type.
I am not sure if I am doing something wrong.

Related

How can I fix "ObjectContext instance has been disposed error"

I developed an application with entity framework. I get the "The ObjectContext instance has been disposed and can no longer be used for operations that require a connection."error from sometimes.
I did some research on the internet but I couldn't figure it out. I would be very grateful if you could help
My DatabaseContext :
public class DatabaseContext :DbContext
{
public DbSet<EvernoteUser> EvernoteUsers { get; set; }
public DbSet<Note> Notes { get; set; }
public DbSet<Comment> Comments { get; set; }
public DbSet<Category> Categories { get; set; }
public DbSet<Liked> Likes { get; set; }
public DatabaseContext()
{
Database.SetInitializer(new MigrateDatabaseToLatestVersion<DatabaseContext,Configuration>());
}
}
My Repository:
public class Repository<T> :IRepository<T> where T : class
{
private DatabaseContext db;
public Repository()
{
db = RepositoryBase.CreateContext();
}
public List<T> List()
{
return db.Set<T>().ToList();
}
public List<T> List(Expression<Func<T,bool>> where)
{
return db.Set<T>().Where(where).ToList();
}
public T Find(Expression<Func<T, bool>> where)
{
return db.Set<T>().FirstOrDefault(where);
}
public IQueryable<T> ListQueryable()
{
return db.Set<T>().AsQueryable<T>();
}
}
}
My RepositoryBase class:
class RepositoryBase
{
protected RepositoryBase()
{
}
private static DatabaseContext _db;
private static object _lockObjesi = new object();
public static DatabaseContext CreateContext()
{
if (_db == null)
{
lock (_lockObjesi)
{
if (_db == null)
{
_db = new DatabaseContext();
}
}
}
return _db;
}
}
Note Entity:
public class Note : MyEntitesBase
{
public string Tittle { get; set; }
public string Text { get; set; }
public bool IsDraft { get; set; }
public int LikeCount { get; set; }
public int CategoryID { get; set; }
public virtual EvernoteUser Owner { get; set; }
public virtual List<Comment> Comments { get; set; }
public virtual Category Category { get; set; }
public virtual List<Liked> Likes { get; set; }
public Note()
{
Comments = new List<Comment>();
Likes = new List<Liked>();
}
}
Comment Entity :
public class Comment : MyEntitesBase
{
public string Text { get; set; }
public bool CommentStatus { get; set; }
public virtual Note Note { get; set; }
public virtual EvernoteUser Owner { get; set; }
}

Filter linq query in entity framework core, many-to-many relationship

I'm using the ASP Net Core 2.
I have a test model:
public class Player
{
public int Id { get; set; }
public string Name { get; set; }
public string Position { get; set; }
public int Age { get; set; }
[IgnoreDataMember]
public ICollection<PlayerTeam> PlayerTeams { get; set; }
public Player()
{
PlayerTeams = new List<PlayerTeam>();
}
}
public class PlayerTeam
{
public int PlayerId { get; set; }
public Player Player { get; set; }
public int TeamId { get; set; }
public Team Team { get; set; }
}
public class Team
{
public int Id { get; set; }
public string Name { get; set; } // название команды
// [IgnoreDataMember]
public ICollection<PlayerTeam> PlayerTeams { get; set; }
public Team()
{
PlayerTeams = new List<PlayerTeam>();
}
}
this is my DBcontext:
public class FootbollContext: DbContext
{
public DbSet<Player> Players { get; set; }
public DbSet<Team> Teams { get; set; }
public FootbollContext(DbContextOptions<FootbollContext> options)
: base(options)
{
}
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<PlayerTeam>()
.HasKey(t => new { t.TeamId, t.PlayerId });
}
}
I have a query in my controller:
FootbollContext db;
var teams = db.Teams.Select(team => new {
TeamName = team.Name,
PlayersOlder20 = team.PlayerTeams.Where(pt => pt.Player.Age > 20).Select(s => s.Player)
});
and it works fine, but I want to use the Include()/ThenInclude() methods for this query, and I want to get the same equal results ie.
var teams = db.Teams.Include(p => p.PlayerTeams).ThenInclude(d => d.Player)
but I don't want to load all data! and I don't know how I can filter results by property "Players age (> 20)" in the relative table (not in the selectable!!) in one SQL Query.

ConnectionStrings DbContext in EF Core

I don't know what I am doing wrong, trying very hard to setup a database project, and keep getting errors related to the connectionstring dbcontext.
I have one applicationdbcontext which is just connecting to localdb
the problem is my other dbcontext which is where my data is seems to be in the wrong place and I am not sure how to fix it. This code is in my models folder
public DbSet<Customer> Customers { get; set; }
public DbSet<Job> Jobs { get; set; }
public DbSet<Order> Orders { get; set; }
public DbSet<Staff> Staff { get; set; }
public DbSet<RequestType> RequestType { get; set; }
public DbSet<CustomerJob> CustomerJobs { get; set; }
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
optionsBuilder.UseSqlServer("Server=(localdb)\\mssqllocaldb;Database=Customers;Trusted_Connection=True;");
}
in startup.cs I have this code..
services.AddDbContext(options =>
options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));
services.AddDbContext(options =>
options.UseSqlServer(Configuration.GetConnectionString("ProdConnection")));
in my appsettings config I have this code..
"ConnectionStrings": {
"DefaultConnection": "Server=(localdb)\\mssqllocaldb;Database=BRSCRM;Trusted_Connection=True;MultipleActiveResultSets=true",
"ProdConnection": "Server=(localdb\\mssqllocaldb;Database=Customers;Trusted_Connection=True;MultipleActiveResults=true"
},
yet when I run my project I get an error that the configuration being supplied is not being used,DI inversion of control indeed, its a bag of cats and its on fire!
You should remove the optionsBuilder.UseSqlServer("... line in your OnConfiguring method.
Then add a constructor to your DbContext class like this;
public YourDbContext(DbContextOptions<YourDbContext> options) : base(options)
{
}
Adding DbContext class..
public class CustomerContext : DbContext
{
public DbSet<Customer> Customers { get; set; }
public DbSet<Job> Jobs { get; set; }
public DbSet<Order> Orders { get; set; }
public DbSet<Staff> Staff { get; set; }
public DbSet<RequestType> RequestType { get; set; }
public DbSet<CustomerJob> CustomerJobs { get; set; }
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
optionsBuilder.UseSqlServer("Server=(localdb)\\mssqllocaldb;Database=Customers;Trusted_Connection=True;");
}
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
//modelBuilder.Entity<CustomerJob>()
// .HasKey(c => new { c.JobId, c.CustomerId });
//code to require a staff member be assigned..
// modelBuilder.Entity<Staff>().Property(s => s.Name).IsRequired();
// modelBuilder.Entity<Customer>().Property(c => c.AssignedStaff).IsRequired();
}
}
public class CustomerJob
{
public int CustomerJobId { get; set; }
public int CustomerId { get; set; }
public DateTime RequestDate { get; set; }
public int JobId { get; set; }
public Job Job { get; set; }
}
public class Job
{
public int JobId { get; set; }
public int CustomerId { get; set; }
public string BusinessName { get; set; }
public string Name { get; set; }
public string JobDescription { get; set; }
public string ServiceType { get; set; }
public string GoogleLink { get; set; }
public string PoisLink { get; set; }
public bool EquisRendered { get; set; }
public bool NadirsRemoved { get; set; }
public string FolderLink { get; set; }
public string ReviewPosted { get; set; }
public string Ingestion { get; set; }
public string Moderated { get; set; }
public bool Delivered { get; set; }
public string CustomerReview { get; set; }
public string PublishedLink { get; set; }
public DateTime RequestDate { get; set; }
public DateTime LastModifiedDate { get; set; }
public DateTime ScheduleShootDate { get; set; }
public DateTime CompletionDate { get; set; }
public List<CustomerJob> CustomerJobs { get; set; }
public Staff AssignedStaff { get; set; }
}
public class Staff
{
public int StaffId { get; set; }
public string Name { get; set; }
public string Phone { get; set; }
public string EMail { get; set; }
}
public class Order
{
public int OrderID { get; set; }
public int CustomerID { get; set; }
public int Order_Detail_Id { get; set; }
public List<Job> Job { get; set; }
}
public class RequestType
{
public int ID { get; set; }
public string Description { get; set; }
}
}
Startup.cs class..
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.AddDbContext<ApplicationDbContext>(options =>
options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));
services.AddDbContext<CustomerContext>();
services.AddIdentity<ApplicationUser, IdentityRole>()
.AddEntityFrameworkStores<ApplicationDbContext>()
.AddDefaultTokenProviders();
// Add application services.
services.AddTransient<IEmailSender, EmailSender>();
// Add Oauth Options
/* Third Party Login Authenticaton Options Google */
services.AddAuthentication().AddGoogle(googleOptions =>
{
googleOptions.ClientId = Configuration["Authentication:Google:ClientId"];
googleOptions.ClientSecret = Configuration["Authentication:Google:ClientSecret"];
});
/* End Google Options */
/* Begin Facebook Options */
services.AddAuthentication().AddFacebook(facebookOptions =>
{
facebookOptions.AppId = Configuration["Authentication:Facebook:AppId"];
facebookOptions.AppSecret = Configuration["Authentication:Facebook:AppSecret"];
});
/* End Facebook Options */
/* Begin Microsoft Options */
services.AddAuthentication().AddMicrosoftAccount(microsoftOptions =>
{
microsoftOptions.ClientId = Configuration["Authentication:Microsoft:ApplicationId"];
microsoftOptions.ClientSecret = Configuration["Authentication:Microsoft:Password"];
});
/* End Microsoft Options */
/* Twitter Options */
services.AddAuthentication().AddTwitter(twitterOptions =>
{
twitterOptions.ConsumerKey = Configuration["Authentication:Twitter:ConsumerKey"];
twitterOptions.ConsumerSecret = Configuration["Authentication:Twitter:ConsumerSecret"];
});
/* End Twitter Options */
/* Begin Identity Options Configuration */
services.AddMvc();
services.AddAuthorization(options =>
{
options.AddPolicy("RequireAdminRole", policy => policy.RequireRole("Admin"));
});
}
Anyways its working now, my mistake was that I had defined the connection in 2 seperate places and I guess that threw an exception.

MVC 5 Complex View Model binding is not working

public class CreateProjeModel
{
public Proje Proje { get; set; }
public List<GeometryModel> GeometryList { get; set; }
public CreateProjeModel()
{
Proje = new Proje();
GeometryList = new List<GeometryModel>();
}
}
public class GeometryModel
{
public List<PointModel> PointList { get; set; }
public GeometryModel()
{
PointList = new List<PointModel>();
}
}
public class PointModel
{
public int X { get; set; }
public int Y { get; set; }
}
public class Proje : EntityBase
{
public int FirmaId { get; set; }
public int IlId { get; set; }
public int? IlceId { get; set; }
public int PlanTurId { get; set; }
public int EtudTurId { get; set; }
public int EtudAmacId { get; set; }
public int DilimId { get; set; }
public string Aciklama { get; set; }
public virtual Firma Firma { get; set; }
public virtual IL Il { get; set; }
public virtual ILCE Ilce { get; set; }
public virtual PlanTur PlanTur { get; set; }
public virtual EtudTur EtudTur { get; set; }
public virtual EtudAmac EtudAmac { get; set; }
public virtual Dilim Dilim { get; set; }
}
I have a complex model named CreateProjeModel. I'm using 'for' to loop collection properties and binding like below:
#Html.TextBoxFor(m => m.GeometryList[i].PointList[j].X)
Action is like below:
[HttpPost]
public async Task<ActionResult> Create(CreateProjeModel proje)
{
//ToDo
return View(proje);
}
Posted data is below:
When it comes to action, GeometryList is empty and Proje's properties are not set to post values. Where am I doing wrong?
Your problem is that your CreateProjeModel model has a property named Proje, but the parameter of your Create() method is also named proje. Your need to change the method signature to (say)
public async Task<ActionResult> Create(CreateProjeModel model)
where the parameter name is not the same as the nae of one of your properties

How to make single view using viewmodel in asp.net mvc 4?

I have different models Image,Page & PageCategories
public class Image
{
public int ImageId { get; set; }
public string ImageTitle { get; set; }
public string ImageURL { get; set; }
}
public class Page
{
public int PageId { get; set; }
public string PageTitle { get; set; }
public string Content { get; set; }
public int PageCategoryId { get; set; }
public virtual PageCategory PageCategory { get; set; }
}
public class PageCategory
{
public int PageCategoryId { get; set; }
public string CategoryName { get; set;
public virtual ICollection<Page> Pages { get; set; }
}
DBContext Class is
class DemoContext:DbContext
{
public DbSet<PageCategory> PageCategories { get; set; }
public DbSet<Page> Pages { get; set; }
public DbSet<Image> Images { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
}
}
I am wondering how to get all the model data to the home page using ViewModel.
For Ex.:
How to get image list and Page list in home page from multiple models?
You may want something like this :
viewModel :
//Create a viewModel with all the properties that you need
public class ViewModel
{
public int ImageId { get; set; }
public string ImageTitle { get; set; }
public string ImageURL { get; set; }
public int PageId { get; set; }
public string PageTitle { get; set; }
public string Content { get; set; }
public int PageCategoryId { get; set; }
public string CategoryName { get; set; }
}
Controller :
...
using (DemoContext db = new DemoContext()){
List<ImagePageViewModel> viewData = (from p in db.Page
join pc from db.PageCategory on p.PageCategoryId equals pc.PageCategoryId
select new ViewModel(){
PageTitle=p.PageTitle,
CategoryName = pc.CategoryName
//... set every property you want
})
}
return View(viewData );
note: I didn't add Image to the query because there is no explicit relation
between Image and the others table so i let you do it.
Create another class and define all above three into it. like below
public class MyView
{
public List<Image> Images { get; set; }
public List<Page> Pages { get; set; }
public List<PageCategory> PageCategories { get; set; }
}
Controller Action:-
public ActionResult Index()
{
MyView myView = // Get it using your logic
return View(myView);
}
finally got my answer:
public class ViewModelDemo
{
public IEnumerable<Image> images { get; set; }
public IEnumerable<Pages> pages { get; set; }
public IEnumerable<PageCategory> pagecategories { get; set; }
}
Then in HomeController
private DemoContext db=new DemoContext();
public ActionResult Index()
{
ViewModelDemo vm = new ViewModelDemo();
vm.images = db.Images.ToList();
vm.pages=db.Pagess.ToList();
vm.pagecategories=db.PageCategories.ToList();
return View(vm);
}

Resources