Custom class for query - asp.net-mvc

I have the following query in my Controller
public ActionResult Index(int Id)
{
var People = from a in db.Person
select a;
var Data = from a in db.Member
where a.Person.PersonId.Equals(Id)
select new CustomObject
{
ProjectId = a.Project.ProjectId,
ProjectName = a.Project.Name,
ProjectCustomer = a.Project.Customer,
ProjectTechProfile = a.Project.TechProfile.Select(x => new
{
x.TechId,
x.Name,
x.Elements
}),
MemberId = a.MemberId,
MemberRole = a.Role,
MemberStart = a.Start,
MemberEnd = a.End
};
And I'm making a custom class for my Data query, but I don't know how to set the property of TechProfile
Right now I have this in my custom class
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
namespace MyProject.Models
{
public class CustomObject
{
public int ProjectId { get; set; }
public string ProjectName { get; set; }
public string ProjectCustomer { get; set; }
public IEnumerable<TechProfile> ProjectTechProfile { get; set; }
public int MemberId { get; set; }
public string MemberRole { get; set; }
public short? MemberStart { get; set; }
public short? MemberEnd { get; set; }
}
}
But the part with
public IEnumerable<TechProfile> ProjectTechProfile { get; set; }
Doesn't work, so do I need to specify TechId, Name and Elements? If so, how?
UPDATE
TechProfile class
namespace MyProject.Models
{
using System;
using System.Collections.Generic;
public partial class TechProfile
{
public int TechId { get; set; }
public string Name { get; set; }
public string Elements { get; set; }
public int ProjectProjectId { get; set; }
public virtual Project Project { get; set; }
}
}

...
ProjectTechProfile = a.Project.TechProfile.Select(x => new TechProfile()
{
TechId = x.TechId,
Name = x.Name,
Elements = x.Elements
},
...

Related

Dictionary requires a model item of type IEnumerable

I'm new to MVC with Linq and in my project, I am getting an error:
The model item passed into the dictionary is of type 'System.Boolean', but this dictionary requires a model item of type 'System.Collections.Generic.IEnumerable`1[Parts.PartsLocation]'.
I am using MVC with EF, so how do I return an IEnumerable?
Here is my Controller:
public async Task<ActionResult> Index(String aContainer)
{
var container = from x in db.PartsLocations select x;
var empty = from y in db.PartsLocations select y;
if (!String.IsNullOrEmpty(aContainer))
{
var parent = from a in db.PartsLocations
where (a.LocationName == aContainer)
select a.ParentLocation;
return View(await parent.ToListAsync());
}
empty = empty.Where(r => r.LocationName.Contains(null));
return View(await empty.ToListAsync());
}
View:
#model IEnumerable<Parts.PartsLocation>
#{
ViewBag.Title = "Index";
}
Model:
namespace Parts
{
using System;
using System.Collections.Generic;
public partial class PartsLocation
{
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")]
public PartsLocation()
{
this.ManufacturingParts = new HashSet<ManufacturingPart>();
}
public int LocationID { get; set; }
public int TypeID { get; set; }
public string LocationName { get; set; }
public string Description { get; set; }
public int PlantID { get; set; }
public Nullable<int> BayID { get; set; }
public Nullable<int> SecurityGroupID { get; set; }
public Nullable<int> ParentLocation { get; set; }
public Nullable<System.DateTime> LastMoved { get; set; }
public string Notes { get; set; }
public virtual LocationType LocationType { get; set; }
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
public virtual ICollection<ManufacturingPart> ManufacturingParts { get; set; }
public virtual ManufacturingPlant ManufacturingPlant { get; set; }
}
}
aContainer Not Null then You have return select
a.ParentLocation
else PartsLocation List
The view model Return Is Difference so Verify The return value

pass multiple data as a list to View in MVC

How to pass LINQ data to View. I have used below code but it throwing conversion error.
namespace WebApplication1.DataContext
{
public class Repositary
{
public ProductMaster productMaster { get; set; }
public ProductDetail productDetail { get; set; }
}
}`
Action Method:-
public ActionResult ProductMasterWithDetails()
{
Model1 db=new Model1();
Repositary rep = new Repositary();
var varResult= from pm in db.ProductMasters join pd in db.ProductDetails on pm.ProductId equals pd.ProductId select new { pm.ProductId, pm.ProductName, pd.Price, pd.ManufactureBy };
ViewBag.result = varResult.ToList();
return View();
}
Error: Cannot initialize type 'WebApplication1.DataContext.Repositary'
with a collection initializer because it does not implement
'System.Collections.IEnumerable'
C:\Users\msnsh\onedrive\documents\visual studio
2013\Projects\WebApplication1\WebApplication1\Controllers\ProductController.cs 55 141 WebApplication1
In View:
#foreach (var result in ViewBag.result){
}
I have two model classes as follows.
namespace WebApplication1.DataContext
{
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Data.Entity.Spatial;
[Table("ProductMaster")]
public partial class ProductMaster
{
public ProductMaster()
{
ProductDetails = new HashSet<ProductDetail>();
}
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.None)]
public int ProductId { get; set; }
[StringLength(50)]
public string ProductName { get; set; }
public virtual ICollection<ProductDetail> ProductDetails { get; set; }
}
}
namespace WebApplication1.DataContext
{
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Data.Entity.Spatial;
public partial class ProductDetail
{
public int? Price { get; set; }
[StringLength(50)]
public string ManufactureBy { get; set; }
public int? ProductId { get; set; }
[Key]
public int ProdDetailsId { get; set; }
public virtual ProductMaster ProductMaster { get; set; }
}
}
If we have two model classes then how to replace below single Model namespace ?
#model IEnumerable
I cannot create a single class as below, because my model has two classes,
public Class ProductCustomModel
{
public int ProductId { get; set; }
public int ProductName { get; set; }
public int Price { get; set; }
public int ManufactureBy { get; set; }
}
Here is my Model1 Class.
namespace WebApplication1.DataContext
{
using System;
using System.Data.Entity;
using System.ComponentModel.DataAnnotations.Schema;
using System.Linq;
using System.Data.Entity.Spatial;
public partial class Model1 : DbContext
{
public Model1()
: base("name=Model1")
{
}
public virtual DbSet<ProductDetail> ProductDetails { get; set; }
public virtual DbSet<ProductMaster> ProductMasters { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<ProductDetail>()
.Property(e => e.ManufactureBy)
.IsUnicode(false);
modelBuilder.Entity<ProductMaster>()
.Property(e => e.ProductName)
.IsUnicode(false);
}
}
}
If you getdata in varResult than you should try,
In Conroller.
Model1 db=new Model1();
var varResult= (from pm in db.ProductMasters join pd in db.ProductDetails on pm.ProductId equals pd.ProductId select new { pm.ProductId, pm.ProductName, pd.Price, pd.ManufactureBy }).ToList();
return View("path to the view",varResult);
In View
#model ModelName
#foreach (var result in Model){
}
You should need to change the ViewBag to the customModel/Class which will send the List to your view.
Models:
namespace WebApplication1.DataContext
{
public class Repositary
{
public ProductMaster productMaster { get; set; }
public ProductDetail productDetail { get; set; }
}
public Class ProductCustomModel
{
public int ProductId { get; set; }
public int ProductName { get; set; }
public int Price { get; set; }
public int ManufactureBy { get; set; }
}
}
Change your action Method to this:
public ActionResult ProductMasterWithDetails()
{
Model1 db=new Model1();
Repositary rep = new Repositary();
var varResult= from pm in db.ProductMasters join pd in db.ProductDetails on pm.ProductId equals pd.ProductId select new { pm.ProductId, pm.ProductName, pd.Price, pd.ManufactureBy };
//Make your List Here like this and add the values in it.
List<ProductCustomModel> productCustomModelList = new List<ProductCustomModel>();
Foreach(ProductCustomModel item in varResult)
{
ProductCustomModel singleData = new ProductCustomModel();
ProductId = item.ProductId,
ProductName = item.ProductName,
Price = item.Price,
ManufactureBy = item.ManufactureBy
productCustomModelList.Add(singleData);
}
return View(productCustomModelList);
}
In the View(.cshtml)
#model IEnumerable<WebApplication1.DataContext.ProductCustomModel>
#foreach (var result in Model){
//.. operations
}

LINQ EF7 ASP.NET and many-to-many

How i could add records to my database , with relation many-to-many in ASP.NET MVC 6 ?
I tried like that, but it's wrong
[HttpPost]
public IActionResult addpersons(Person pers)
{
var ourdoc = db.Documents.FirstOrDefault(p => p.Documentid == docselected);
ourdoc.DocPers.Add(ourdoc);
db.SaveChanges();
return Content("s");
}
Listings of my model files :
DocContext.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.Data.Entity;
namespace TDS_1_ASPNETMVC6.Models
{
public class DocPer
{
public int Documentid { get; set; }
public Document Document { get; set; }
public int Personid { get; set; }
public Person Person { get; set; }
}
public class DocContext : DbContext
{
public virtual DbSet<Document> Documents { get; set; }
public virtual DbSet<Person> Persons { get; set; }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<DocPer>()
.HasKey(t => new
{
t.Documentid,
t.Personid
});
modelBuilder.Entity<DocPer>()
.HasOne(pt => pt.Document)
.WithMany(p => p.DocPers)
.HasForeignKey(pt => pt.Documentid);
modelBuilder.Entity<DocPer>()
.HasOne(pt => pt.Person)
.WithMany(t => t.DocPers)
.HasForeignKey(pt => pt.Personid);
}
}
}
Documents.cs
using System.Collections.Generic;
namespace TDS_1_ASPNETMVC6.Models
{
public class Document
{
public int Documentid { get; set; }
public string Name { get; set; }
public string Props { get; set; }
public List<DocPer> DocPers { get; set; }
}
}
Person.cs
using System.Collections.Generic;
namespace TDS_1_ASPNETMVC6.Models
{
public class Person
{
public int Personid { get; set; }
public string Iname { get; set; }
public string Fname { get; set; }
public string Oname { get; set; }
public string Email { get; set; }
public List<DocPer> DocPers { get; set; }
}
}
First, your controller is not checking for null; what if var ourdoc = db.Documents.FirstOrDefault(p => p.Documentid == docselected); is null? So check for null first :)
Also ourdoc.DocPers.Add(ourdoc); must be changed to ourdoc.DocPers.Add(new DocPer {Person = person});
Second, to create a many-to-many I suggest you to remove the DocPer table and map it "behind", like this:
public class Document
{
public Document()
{
Persons = new List<Person>();
}
public int Documentid { get; set; }
public string Name { get; set; }
public string Props { get; set; }
public virtual ICollection<Person> Persons { get; set; }
}
public class Person
{
public Person()
{
Documents = new List<Document>();
}
public int Personid { get; set; }
public string Iname { get; set; }
public string Fname { get; set; }
public string Oname { get; set; }
public string Email { get; set; }
public virtual ICollection<Document> Documents { get; set; }
}
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<Document>()
.HasMany<Person>(s => s.Persons)
.WithMany(c => c.Documents)
.Map(cs =>
{
cs.MapLeftKey("Documentid");
cs.MapRightKey("Personid");
cs.ToTable("DocPer");
});
}
DocPer table will be managed by the EF without exposing it. Check this site for more details. This guide will apply to EF6 only, not EF7 (which does not support many-to-many yet, for that support check this link). BTW, EF7 is still is not stable yet, so is possibile that this support will be offered in the future, but no one knows yet.

Model or ViewModel in a ListViewModel

Should T be a for example Customer or CustomerViewModel ?
The annotations bound to Mvc namespace are on the ListViewModel so actually I could pass the Customer object. What do you think?
public class ListViewModel<T>
{
[Required(ErrorMessage="No item selected.")]
public int[] SelectedIds { get; set; }
public IEnumerable<T> DisplayList { get; set; }
}
UPDATE
[HttpGet]
public ActionResult Open()
{
IEnumerable<Testplan> testplans = _testplanDataProvider.GetTestplans();
OpenTestplanListViewModel viewModel = new OpenTestplanListViewModel(testplans);
return PartialView(viewModel);
}
public class OpenTestplanListViewModel
{
public OpenTestplanListViewModel(IEnumerable<Testplan> testplans)
{
var testplanViewModels = testplans.Select(t => new TestplanViewModel
{
Name = string.Format("{0}-{1}-{2}-{3}", t.Release.Name, t.Template.Name, t.CreatedAt, t.CreatedBy),
TestplanId = t.TestplanId,
});
DisplayList = testplanViewModels;
}
[Required(ErrorMessage = "No item selected.")]
public int[] SelectedIds { get; set; }
public string Name { get; set; }
public IEnumerable<TestplanViewModel> DisplayList { get; private set; }
}
public class TestplanViewModel
{
public int TestplanId { get; set; }
public string Name { get; set; }
}
public class Testplan
{
public int TestplanId { get; set; }
public int TemplateId { get; set; }
public int ReleaseId { get; set; }
public string CreatedBy { get; set; }
public DateTime CreatedAt { get; set; }
public Template Template { get; set; }
public Release Release { get; set; }
}
T should ideally be a view model. Having a view model referencing domain models is some kind of a hybrid view model, not a real one. But if you think that in this specific case the domain model will be exactly the same as the view model then you could keep it as well.

DropDownList in wrapper class for two classes

My problem started when I wrap three classes
the first class is
[Bind(Exclude="ID")]
public class Material
{
public string MaterialName { get; set; }
}
the second class is
[Bind(Exclude="ID")]
public class ExameState
{
public string ExamState { get; set; }
}
the third class is
[Bind(Exclude="ID")]
public class Exams
{
public string ExamsName { get; set; }
public DateTime CreationDate { get; set; }
public DateTime StartingDate { get; set; }
public int Period { get; set; }
public int ExamStateID { get; set; }
public int MaterialID { get; set; }
public int GroupID { get; set; }
public int QuestionState { get; set; }
public int TeacherID { get; set; }
public int ExamMarkState { get; set; }
public string Password { get; set; }
}
wrapper class is
public class Examswrapper
{
public Material material { get; set; }
public ExameState examstate { get; set; }
public Exam exam { get; set; }
}
I need to display dropdownlist for Material with datavalue=MaterialName
and key=ID in view build on Examswrapper class
I am trying this
how to make it
and thank you for your advice
new error :
System.NullReferenceException: Object reference not set to an instance of an object.
There is a problem with your view model because the Material property should be a collection if you want a drop down list. Also your Material class is missing an ID property. So:
public class Material
{
public string ID { get; set; }
public string MaterialName { get; set; }
}
public class ExamsViewModel
{
public string SelectedMaterialId { get; set; }
public IEnumerable<Material> Materials { get; set; }
... // some other properties
}
and then in your strongly typed view:
<%= Html.DropDownListFor(
// This is the property that will hold the selected value
x => x.SelectedMaterialId,
// Build the select list based on the Model.Materials collection
new SelectList(
Model.Materials.Select(material => new SelectListItem
{
Value = material.ID,
Text = material.MaterialName
}),
"Value", "Text"
)
) %>
#Html.DropDownListFor(model => model.material,
Model.material.Select(
x => new SelectListItem
{
Text = x.MaterialName,
Value = x.Id
}
))

Resources