EF 5.0 (Database-First Model) not working on one table - entity-framework-5

I have a database table called TBLFIRM. I am using acc database-first model. EF prepares the sql wrong. What can be wrong on this object?
Thank you
My Syntax, a very simple call:
TBLFIRM d = VT.TBLFIRMs.FirstOrDefault(p => p.ID > 0);
The SQL syntax that EF 5 prepares
SELECT TOP (1)
[Extent1].[ID] AS [ID],
[Extent1].[DISTID] AS [DISTID],
[Extent1].[SESSIONKEY] AS [SESSIONKEY],
[Extent1].[NAME] AS [NAME],
[Extent1].[PHONE] AS [PHONE],
[Extent1].[EMAIL] AS [EMAIL],
[Extent1].[CREATEUSER] AS [CREATEUSER],
[Extent1].[CREATEDATE] AS [CREATEDATE],
[Extent1].[UPDATEUSER] AS [UPDATEUSER],
[Extent1].[UPDATEDATE] AS [UPDATEDATE],
[Extent1].[AUTHORIZEDUSERNAME] AS [AUTHORIZEDUSERNAME],
[Extent1].[AUTHORIZEDUSEREMAIL] AS [AUTHORIZEDUSEREMAIL],
[Extent1].[AUTHORIZEDUSERPHONE] AS [AUTHORIZEDUSERPHONE],
[Extent1].[SENDEMAIL] AS [SENDEMAIL],
[Extent1].[REPLYEMAIL] AS [REPLYEMAIL],
[Extent1].[ACTIVE] AS [ACTIVE],
[Extent1].[CANLOGIN] AS [CANLOGIN],
[Extent1].[INTERNALNAME] AS [INTERNALNAME],
[Extent1].[TBLDISTRIBUTOR_ID] AS [TBLDISTRIBUTOR_ID]
FROM [dbo].[TBLFIRMs] AS [Extent1]
WHERE [Extent1].[ID] > 0
Context Class
public DbSet<TBLFIRM> TBLFIRMs { get; set; }
TBLFirm Class
public partial class TBLFIRM
{
public TBLFIRM()
{
this.TBLFIRMSETTINGS = new HashSet<TBLFIRMSETTING>();
this.TBLFIRMSMTPs = new HashSet<TBLFIRMSMTP>();
this.TBLMAILFIRMMATCHes = new HashSet<TBLMAILFIRMMATCH>();
this.TBLMAILGROUPs = new HashSet<TBLMAILGROUP>();
this.TBLMAILTEMPLATEs = new HashSet<TBLMAILTEMPLATE>();
this.TBLSCHEDULEs = new HashSet<TBLSCHEDULE>();
this.TBLUSERGROUPs = new HashSet<TBLUSERGROUP>();
this.TBLUSERS = new HashSet<TBLUSER>();
}
public int ID { get; set; }
public int DISTID { get; set; }
public string SESSIONKEY { get; set; }
public string NAME { get; set; }
public string PHONE { get; set; }
public string EMAIL { get; set; }
public string CREATEUSER { get; set; }
public Nullable<System.DateTime> CREATEDATE { get; set; }
public string UPDATEUSER { get; set; }
public Nullable<System.DateTime> UPDATEDATE { get; set; }
public string AUTHORIZEDUSERNAME { get; set; }
public string AUTHORIZEDUSEREMAIL { get; set; }
public string AUTHORIZEDUSERPHONE { get; set; }
public string SENDEMAIL { get; set; }
public string REPLYEMAIL { get; set; }
public Nullable<bool> ACTIVE { get; set; }
public Nullable<bool> CANLOGIN { get; set; }
public string INTERNALNAME { get; set; }
public virtual TBLDISTRIBUTOR TBLDISTRIBUTOR { get; set; }
public virtual ICollection<TBLFIRMSETTING> TBLFIRMSETTINGS { get; set; }
public virtual ICollection<TBLFIRMSMTP> TBLFIRMSMTPs { get; set; }
public virtual ICollection<TBLMAILFIRMMATCH> TBLMAILFIRMMATCHes { get; set; }
public virtual ICollection<TBLMAILGROUP> TBLMAILGROUPs { get; set; }
public virtual ICollection<TBLMAILTEMPLATE> TBLMAILTEMPLATEs { get; set; }
public virtual ICollection<TBLSCHEDULE> TBLSCHEDULEs { get; set; }
public virtual ICollection<TBLUSERGROUP> TBLUSERGROUPs { get; set; }
public virtual ICollection<TBLUSER> TBLUSERS { get; set; }
}

After a deeper research I was able to find and fix the problem thanks to a reply by BRian Rogers # Code First vs. Database First.
If you are approaching Database or Model First the the connection string must have a metadata, otherwise EF interprets this as Code First approach.
As I was calling the library holding EF objects from a web site, the web.config's connectionstring was a plaing database connection.
<add name="EmmContext" connectionString="Data Source=.;Initial Catalog=GPMM;Persist Security Info=True;User ID=********;Pwd=******" providerName="System.Data.SqlClient"/>
After changing it to
<add name="EmmContext" connectionString="metadata=res://*/DAL.DBModel.csdl|res://*/DAL.DBModel.ssdl|res://*/DAL.DBModel.msl;provider=System.Data.SqlClient;provider connection string="data source=.;initial catalog=GPMM;persist security info=True;user id=*******;password=********;MultipleActiveResultSets=True;App=EntityFramework"" providerName="System.Data.EntityClient"/>
it worked like a charm.
Just wanted to share this particular experience. Thank you Brian Rogers! :-)

Related

Configuring AutoMapper in ASP.NET Core

I am trying to use automapper 8.0.0 to fill a list of WorkViewModel.
This list is getting data from the Work class out of the database using entity framework.
How ever it looks like something is going wrong with initializing as throwing follows error:
InvalidOperationException: Mapper not initialized
What am I doing wrong?
I have setup the following code!
Startup.cs
services.AddAutoMapper();
Function being called:
public async Task<IEnumerable<WorkViewModel>> GetAllAsync()
{
IList<Work> works = await _context.Work.ToListAsync();
IList<WorkViewModel> viewModelList = Mapper.Map<IList<Work>, IList<WorkViewModel>>(works);
return viewModelList;
}
Configuration:
public class MappingProfile : Profile
{
public MappingProfile()
{
Mapper.Initialize(cfg =>
{
cfg.CreateMap<WorkViewModel, Work>();
});
}
}
WorkViewModel:
public class WorkViewModel
{
public int WorkID { get; set; }
public string Name { get; set; }
public byte[] Tumbmail { get; set; }
public string Discription { get; set; }
public string Client { get; set; }
public DateTime Date { get; set; }
public string PreviewLink { get; set; }
public string GitLink { get; set; }
public string DownloadLink { get; set; }
public int DetailID { get; set; }
public byte[] Banner { get; set; }
public string Documentation { get; set; }
public int CategoryID { get; set; }
public string Category { get; set; }
}
Work Model:
public class Work
{
[Key]
public int WorkID { get; set; }
[Display(Name = "Project Name")]
public string Name { get; set; }
[Display(Name = "Client name")]
public string Client { get; set; }
[Display(Name = "Description")]
public string Discription { get; set; }
[Display(Name = "Date")]
public DateTime Date { get; set; }
[Display(Name = "Thumbmail")]
public byte[] Tumbmail { get; set; }
[Display(Name = "Preview Link")]
public string PreviewLink { get; set; }
[Display(Name = "Git Link")]
public string GitLink { get; set; }
[Display(Name = "DownloadLink")]
public string DownloadLink { get; set; }
public WorkCategory workCategory { get; set; }
public WorkDetailed WorkDetailed { get; set; }
}
Only adding services.AddAutoMapper(); to the ConfigureServices method would not work for you. You have to configure AutoMapper as follows:
public void ConfigureServices(IServiceCollection services)
{
// Auto Mapper Configurations
var mappingConfig = new MapperConfiguration(mc =>
{
mc.AddProfile(new MappingProfile());
});
IMapper mapper = mappingConfig.CreateMapper();
services.AddSingleton(mapper);
services.AddMvc();
}
And also don't forget to install the AutoMapper.Extensions.Microsoft.DependencyInjection nuget package.

Need Help Displaying The Name Instead of a GUID in a DataTable in MVC 5

I need some help displaying the name instead of a GUID inside a DataTable in MVC 5.
I implemented the DataTable by following this tutorial: https://www.c-sharpcorner.com/article/ajax-crud-operation-with-jquery-datatables-in-asp-net-mvc-5-for-beginners/
I am trying to show the names for a Municipal Region, Municipality and Client Status. It shows perfectly fine inside my details view model, however it displays the GUID in the DataTable. I have spent days trying to figure this out to no avail.
Here is the code for the DataTable in my controller:
public ActionResult Get([ModelBinder(typeof(DataTablesBinder))] IDataTablesRequest requestModel, ClientsAdvancedSearchViewModel searchViewModel)
{
IQueryable<Client> query = DbContext.Clients;
var totalCount = query.Count();
// searching and sorting
query = SearchClients(requestModel, searchViewModel, query);
var filteredCount = query.Count();
// Paging
query = query.Skip(requestModel.Start).Take(requestModel.Length);
var data = query.Select(client => new
{
ClientIdentifier = client.ClientIdentifier,
CompanyName = client.CompanyName,
ClientContactPerson = client.ClientContactPerson,
ClientEmail = client.ClientEmail,
ClientTel = client.ClientTel,
Consultant = client.Consultant,
Town = client.Town,
Suburb = client.Suburb,
MunicipalRegionID = client.MunicipalRegionID,
MunicipalityID = client.MunicipalityID,
ClientStatusID = client.ClientStatusID,
}).ToList();
return Json(new DataTablesResponse(requestModel.Draw, data, filteredCount, totalCount), JsonRequestBehavior.AllowGet);
}
And here is the code for my client class:
public class Client
{
[Key]
public System.Guid ClientIdentifier { get; set; }
public string CompanyName { get; set; }
public string SiteName { get; set; }
public string Status { get; set; }
public string Consultant { get; set; }
public string Comments { get; set; }
[DataType(DataType.Date)]
[DisplayFormat(DataFormatString = "{0:yyyy-MM-dd}", ApplyFormatInEditMode = true)]
public Nullable<System.DateTime> Date { get; set; }
public string ClientInformation { get; set; }
public string ClientContactPerson { get; set; }
public string ClientEmail { get; set; }
public string ClientTel { get; set; }
public string ClientAddress { get; set; }
public string GPSCoordinates { get; set; }
public string Town { get; set; }
public string Suburb { get; set; }
public System.Guid MunicipalRegionID { get; set; }
public System.Guid MunicipalityID { get; set; }
public System.Guid ClientStatusID { get; set; }
public string CreatedBy { get; set; }
public Nullable<System.DateTime> DateCreated { get; set; }
public string LastEditedBy { get; set; }
public Nullable<System.DateTime> DateLastEdited { get; set; }
}
Here is the code for my Municipal Region Class:
public class MunicipalRegion
{
[Key]
public System.Guid MunicipalRegionIdentifier { get; set; }
public string MunicipalRegionName { get; set; }
public string CreatedBy { get; set; }
public Nullable<System.DateTime> DateCreated { get; set; }
public string LastEditedBy { get; set; }
public Nullable<System.DateTime> DateLastEdited { get; set; }
}
Here is the code for my Municipality Class:
public class Municipality
{
[Key]
public System.Guid MunicipalityIdentifier { get; set; }
public string MunicipalityName { get; set; }
public System.Guid MunicipalRegionID { get; set; }
public string CreatedBy { get; set; }
public Nullable<System.DateTime> DateCreated { get; set; }
public string LastEditedBy { get; set; }
public Nullable<System.DateTime> DateLastEdited { get; set; }
Here is the code for my Client Status Class:
public class ClientStatus
{
[Key]
public System.Guid ClientStatusIdentifier { get; set; }
public string ClientStatusName { get; set; }
public string CreatedBy { get; set; }
public Nullable<System.DateTime> DateCreated { get; set; }
public string LastEditedBy { get; set; }
public Nullable<System.DateTime> DateLastEdited { get; set; }
}
Help would be appreciated. Thank you :)
I may be wrong but it sounds like you are trying to hide the key fields from generated views. This can be accomplished adding the following annotation.
[Display(AutoGenerateField=false)]
Ok, I see what you are trying to do now. The main problem is your classes are not set up correctly. From a database perspective they are correct but from a class perspective, they won't return what you want.
You need to set up your classes as follows
Client Class
public Client()
{
Municipality = new Municipality();
Status = new ClientStatus();
}
[Key]
public System.Guid ClientIdentifier { get; set; }
public string CompanyName { get; set; }
public string SiteName { get; set; }
public string Consultant { get; set; }
public string Comments { get; set; }
[DataType(DataType.Date)]
[DisplayFormat(DataFormatString = "{0:yyyy-MM-dd}", ApplyFormatInEditMode = true)]
public Nullable<System.DateTime> Date { get; set; }
public string ClientInformation { get; set; }
public string ClientContactPerson { get; set; }
public string ClientEmail { get; set; }
public string ClientTel { get; set; }
public string ClientAddress { get; set; }
public string GPSCoordinates { get; set; }
public string Town { get; set; }
public string Suburb { get; set; }
public string CreatedBy { get; set; }
public Nullable<System.DateTime> DateCreated { get; set; }
public string LastEditedBy { get; set; }
public Nullable<System.DateTime> DateLastEdited { get; set; }
// Create Forign Key Connections
public Municipality Municipality { get; set; }
public ClientStatus Status { get; set; }
}
Municipality Class
public class Municipality
{
public Municipality() {
MunicipalRegion = new MunicipalRegion();
}
[Key]
public System.Guid MunicipalityIdentifier {
get;
set;
}
public string MunicipalityName { get; set; }
public string CreatedBy { get; set; }
public Nullable<System.DateTime> DateCreated { get; set; }
public string LastEditedBy { get; set; }
public Nullable<System.DateTime> DateLastEdited { get; set; }
public MunicipalRegion MunicipalRegion { get; set; }
}
This will allow you to produce output using something similar to
var data = clients.Select(cl => new
{
ClientIdentifier = cl.ClientIdentifier,
CompanyName = cl.CompanyName,
MunicipalRegion = cl.Municipality.MunicipalityName,
Status = cl.Status.ClientStatusName
});

Automapper is mapping incorrectly?

I have two objects, Project is a DB entity and IProject which I am trying to save to the database:
public interface IProject
{
int ProjectID { get; set; }
string JobNumber { get; set; }
string JobName { get; set; }
string ProjectLocation { get; set; }
int? FeeTypeID { get; set; }
decimal? Fee { get; set; }
decimal? ConstructionCost { get; set; }
decimal? CostPerSquareFoot { get; set; }
decimal? SquareFoot { get; set; }
string Memo { get; set; }
DateTime? DateCompleted { get; set; }
int JobStatusID { get; set; }
int ProjectTypeID { get; set; }
}
//The inheritance is actually in a partial class that doesn't get overridden
public partial class Project : IProject
{
public Project()
{
this.ProjectContacts = new HashSet<ProjectContact>();
this.ProjectConsultants = new HashSet<ProjectConsultant>();
}
public int ProjectID { get; set; }
public string JobNumber { get; set; }
public string JobName { get; set; }
public Nullable<int> FeeTypeID { get; set; }
public Nullable<decimal> Fee { get; set; }
public int JobStatusID { get; set; }
public string Memo { get; set; }
public Nullable<decimal> Acreage { get; set; }
public Nullable<decimal> SquareFoot { get; set; }
public Nullable<decimal> ConstructionCost { get; set; }
public Nullable<decimal> BudgetPrice { get; set; }
public Nullable<decimal> ActualPrice { get; set; }
public Nullable<System.DateTime> DateCompleted { get; set; }
public Nullable<decimal> CostPerSquareFoot { get; set; }
public string ProjectLocation { get; set; }
public int ProjectTypeID { get; set; }
public Nullable<System.DateTime> StartDate { get; set; }
public Nullable<int> PhaseID { get; set; }
public string ProjectDescription { get; set; }
public Nullable<int> ArchitectID { get; set; }
public Nullable<int> ManagerID { get; set; }
public Nullable<int> ArchiveLocationID { get; set; }
public virtual ICollection<ProjectContact> ProjectContacts { get; set; }
public virtual FeeType FeeType { get; set; }
public virtual JobStatu JobStatu { get; set; }
public virtual ICollection<ProjectConsultant> ProjectConsultants { get; set; }
public virtual Person Person { get; set; }
public virtual ArchiveLocation ArchiveLocation { get; set; }
public virtual Person Person1 { get; set; }
public virtual Phase Phase { get; set; }
public virtual ProjectType ProjectType { get; set; }
}
I have my Map created:
Mapper.CreateMap<IProject, Data.Project>();
but for some reason whenever I call the map:
//mappingService is a wrapper I have around Automapper so that I can inject it
var project = _mappingService.Map<IProject, Data.Project>(request);
I get this error:
Missing type map configuration or unsupported mapping.
Mapping types:
RuntimeType -> FeeType
System.RuntimeType -> Renaissance.Data.FeeType
Destination path:
Project.FeeType.FeeType
Source value:
System.Decimal
I am not at any point trying to do that. The names match and even if I specifically tell it to map with:
.ForMember(dest => dest.Fee, opt => opt.MapFrom(src => src.Fee))
It still errors with the same message.
What am I missing?
UPDATE
This works:
.ForMember(dest => dest.FeeType, opt => opt.Ignore());
I think it is a hack that I need to do that. I shouldn't have to ignore a property in the destination that does not exist / is not named the same as something in the source property.

CRUD multiple model in one view in mvc4

i want use multiple model in one view and add records in multiple table from view
my db like below image:
(i work with vs2012 mvc4 and EF)
i create four model for each table and class "PreOrder" for repository of all
public class Orders
{
public long OrdersId { get; set; }
public string CustomerId { get; set; }
public long OrderListId { get; set; }
public int? CountProduct { get; set; }
public string CountPrice { get; set; }
public string VisitorsName { get; set; }
public DateTime? OrderDate { get; set; }
}
public class Product
{
public string ProductID { get; set; }
public string NameProduct { get; set; }
public string Price { get; set; }
}
public class Customers
{
public string CustomerID { get; set; }
[DisplayFormat(NullDisplayText = "-")]
public string Name { get; set; }
[DisplayFormat(NullDisplayText = "-")]
...
}
public class OrderList
{
public long OrderListID { get; set; }
public Nullable<long> OrdersId { get; set; }
public string ProductId { get; set; }
public Nullable<int> Count { get; set; }
public Nullable<decimal> DisCount { get; set; }
}
public class PreOrder
{
public Customers _Customer { set; get; }
public Product _Product { set; get; }
public Orders _Order { set; get; }
public OrderList _OrderList { set; get; }
}
i want use name,family,customerid from tblcustomers
and productId,NameProduct,Price from tblProducts
and all fields of tblOrders and tblOrderList
how can i create one view to fill tables Orders and OrderList??
i solved problem like below article:
How to Use ViewModel with ASP.NET MVC ?
How to Use ValueInjecter with Asp.net MVC ViewModel ?

EF Code First - Many To Many

I have a problem with devising a many to many relationship in code first. EF is creating the Junction table and associating the Fk's as I would expect, however when i try to access the User's MailingList collection, there are no entries.
I've implemented test data on Initialise via Seeding, the data is al present in the database.
I think the problem lies with the constructors for Users and MailingLists, but I'm uncertain. I want to be able to navigate the navigational property of User.MailingLists.
var user = db.Users.Find(1);
Console.WriteLine("{0}", user.EmailAddress); //This is Fine
Console.WriteLine("{0}", user.Address.PostCode); /This is Fine
foreach (MailingList ml in user.MailingLists) // this is 0
{
Console.WriteLine("{0}", ml.Name);
}
My model is below:-
public class User : IEntityBase
{
public User()
{
MailingLists = new List<MailingList>();
}
public int Id { get; set; }
public string Forename { get; set; }
public string Surname { get; set; }
public string EmailAddress { get; set; }
public DateTime? DateLastUpdated { get; set; }
public DateTime DateCreated { get; set; }
public bool IsDeleted { get; set; }
public virtual Address Address { get; set; }
public ICollection<MailingList> MailingLists { get; set; }
}
public class MailingList : IEntityBase
{
public MailingList()
{
Users = new List<User>();
}
public int Id { get; set; }
public string Name { get; set; }
public DateTime? DateLastUpdated { get; set; }
public DateTime DateCreated { get; set; }
public bool IsDeleted { get; set; }
public ICollection<User> Users { get; set; }
}
public class Address : IEntityBase
{
public int Id { get; set; }
public string AddressLine1 { get; set; }
public string AddressLine2 { get; set; }
public string AddressLine3 { get; set; }
public string City { get; set; }
public string County { get; set; }
public string PostCode { get; set; }
public DateTime? DateLastUpdated { get; set; }
public DateTime DateCreated { get; set; }
public bool IsDeleted { get; set; }
}
Any suggestions welcome.
You are neither eager loading the MailingList entries with the query, nor fulfulling the requirements for a lazy loading proxy so there is no way EF can populate the collection.
To allow lazy loading, change the MailingList property to be virtual to allow the EF proxy to override it.
To use eager loading, use Include() (an extension method in System.Data.Entity) in the query to specify that the MailingList should be loaded.

Resources