The table is created in the database, but every request in the software to get database information throws this error:
No suitable constructor was found for entity type 'HierarchyId'. The following constructors had parameters that could not be bound to properties of the entity type: cannot bind 'value' in 'HierarchyId(SqlHierarchyId value)'.
This is my Entity class
public class OrganizationalPosition: AuditedAggregateRoot<long>
{
public OrganizationalPosition()
{
}
public OrganizationalPosition(string title, HierarchyId organizationNode,HierarchyId parentNode)
{
SetTitle(title);
Node = organizationNode;
ParentNode = parentNode;
NodeText = Node.ToString();
NodeLevel = Node.GetLevel();
}
public string Title { get; private set; }
public HierarchyId Node { get; private set; }
public HierarchyId ParentNode { get; set; }
public long ParentId { get; set; }
public string NodeText { get; set; }
public int NodeLevel { get; set; }
public OrganizationalPosition Parent { get; set; }
public ICollection<OrganizationalPosition> Children { get; set; }
public ICollection<OrganizationUser> Users { get; set; }
public void SetTitle(string title)
{
if (title.Length is < 2 or > 100)
throw new FormatException($"{nameof(title)} is not valid");
Title = title;
}
}
This is my DbSet
public DbSet<OrganizationalPosition> OrganizationalPositions { get; set; }
This is my Configure
builder.Entity<OrganizationalPosition>(b =>
{
b.ToTable(HumanResourceDbProperties.DbTablePrefix + "OrganizationalPositions",
HumanResourceDbProperties.DbSchema);
b.ConfigureByConvention();
b.HasOne(x => x.Parent)
.WithMany(x => x.Children)
.HasForeignKey(x => x.ParentId)
.OnDelete(DeleteBehavior.NoAction)
.IsRequired();
b.Property(x => x.Node)
.IsRequired();
b.Property(x => x.Title)
.HasMaxLength(200)
.IsRequired();
b.Property(x => x.NodeText)
.HasMaxLength(200)
.IsRequired();
b.Property(x => x.NodeLevel)
.IsRequired();
b.HasIndex(x => new { x.Node }).IsUnique();
});
This is my MigrationsDbContext
public HumanResourceHttpApiHostMigrationsDbContext CreateDbContext(string[] args)
{
var configuration = BuildConfiguration();
var builder = new
DbContextOptionsBuilder<HumanResourceHttpApiHostMigrationsDbContext>()
.UseSqlServer(configuration.GetConnectionString("HumanResource"),
x => x.UseHierarchyId());
return new HumanResourceHttpApiHostMigrationsDbContext(builder.Options);
}
this is my package that I am installed
<PackageReference Include="EntityFrameworkCore.SqlServer.HierarchyId" Version="3.0.1" />
<PackageReference Include="Volo.Abp.Ddd.Domain" Version="5.3.2" />
<ProjectReference Include="..\YesnaPars.HumanResource.Domain.Shared\YesnaPars.HumanResource.Domain.Shared.csproj" />
This link didn't help me either
No suitable constructor found for entity type HierarchyId
I am using ASP.NET MVC and Automapper.
I have tried to solve this problem, I can not insert data to the database by this code and if I insert the data by using SQL Server the error (Automapper mapping exception) is coming.
How can I solve this problem?
Controller code:
public class SERVICESController : Controller
{
private readonly IMapper mapper;
private readonly Calssifications1 calssificationInterface;
private readonly CATEGORIES categorisInterface;
private readonly CHANNELS1 channelsInterface;
private readonly Level LEVELInterface;
private readonly User userInterface;
private readonly Services1 serviceInterface;
// GET: SERVICES
public SERVICESController()
{
mapper = AutoMapperConfig.Mapper;
calssificationInterface = new Calssifications1();
categorisInterface = new CATEGORIES();
channelsInterface = new CHANNELS1();
LEVELInterface = new Level();
userInterface = new User();
serviceInterface = new Services1();
}
//index
public ActionResult Index(string query = null,
int? CATID = null,
int? TYPID = null,
int? CLASSID = null,
int? LEVELID = null,
int? CHANNELID = null)
{
var serviceListData = new ServiceListModel();
InitSelectList(ref serviceListData);
var serviceList = serviceInterface.ReadAll(query, CATID, TYPID,
CLASSID, LEVELID, CHANNELID);
var mappedServiceList = mapper.Map<List<SERVICESmodel>>(serviceList);
serviceListData.SERVICEs = mappedServiceList;
return View(serviceListData);
}
//create function
public ActionResult Create()
{
var serviceModel = new SERVICESmodel();
InitSelectList(ref serviceModel);
return View(serviceModel);
}
[HttpPost]
public ActionResult Create(SERVICESmodel serviceData)
{
InitSelectList(ref serviceData);
try
{
if (ModelState.IsValid)
{
serviceData.MANUAL = SaveManualFile(serviceData.MANUALfile);
var STO = mapper.Map<SERVICE_ALL>(serviceData);
STO.CATEGORy = null;
STO.USER_TYPE = null;
STO.CALSSIFICATION = null;
STO.MATURITY_LEVEL = null;
STO.CHANNEL = null;
int result = serviceInterface.Create(STO);
if (result >= 1)
{
return RedirectToAction("Index");
}
ViewBag.Message = "An Error ";
}
return View(serviceData);
}
catch (Exception ex)
{
ViewBag.Message = ex.Message;
return View(serviceData);
}
}
//function servicemodel
private void InitSelectList(ref SERVICESmodel serviceModel)
{
var mappedCategriesList = GetCategories();
serviceModel.Categories = new SelectList(mappedCategriesList, "ID", "NAME");
var mappedUserlList = GetUser();
serviceModel.UserType = new SelectList(mappedUserlList, "ID", "NAME");
var mappedLevellList = GetLevel();
serviceModel.Level = new SelectList(mappedLevellList, "ID", "NAME");
var mappedClasslList = GetClass();
serviceModel.Class = new SelectList(mappedClasslList, "ID", "NAME");
var mappedChannelList = GetChannel();
serviceModel.Channel = new SelectList(mappedChannelList, "ID", "NAME");
}
//function servise list model
private void InitSelectList(ref ServiceListModel serviceList)
{
var mappedCategoriesList = GetCategories();
serviceList.Categories = new SelectList(mappedCategoriesList, "ID", "Name");
var mappedLevelList = GetLevel();
serviceList.Level = new SelectList(mappedLevelList, "ID", "Name");
var mappedChannelList = GetChannel();
serviceList.Channel = new SelectList(mappedChannelList, "ID", "Name");
var mappedUserlList = GetUser();
serviceList.UserType = new SelectList(mappedUserlList, "ID", "Name");
var mappedClassList = GetClass();
serviceList.Class = new SelectList(mappedClassList, "ID", "Name");
}
private IEnumerable<CATEGORIESmodel> GetCategories()
{
var categories = categorisInterface.ReadAll();
return mapper.Map<IEnumerable<CATEGORIESmodel>>(categories);
}
private IEnumerable<MATURITY_LEVELmodel> GetLevel()
{
var Levels = LEVELInterface.ReadAll();
return mapper.Map<IEnumerable<MATURITY_LEVELmodel>>(Levels);
}
private IEnumerable<CHANNELSmodel> GetChannel()
{
var Channels1 = channelsInterface.ReadAll();
return mapper.Map<IEnumerable<CHANNELSmodel>>(Channels1);
}
private IEnumerable<USER_TYPEmodel> GetUser()
{
var Users = userInterface.ReadAll();
return mapper.Map<IEnumerable<USER_TYPEmodel>>(Users);
}
private IEnumerable<CALSSIFICATIONmodel> GetClass()
{
var Classes = calssificationInterface.ReadAll();
return mapper.Map<IEnumerable<CALSSIFICATIONmodel>>(Classes);
}
// Function save file
private string SaveManualFile(HttpPostedFileBase MANUALfile, string currentFile = "")
{
if (MANUALfile != null)
{
var fileExtenstion = Path.GetExtension(MANUALfile.FileName);
var imageGuid = Guid.NewGuid().ToString();
string imageId = imageGuid + fileExtenstion;
// Save new file
string filePath = Server.MapPath($"~/Upload/{imageId}");
MANUALfile.SaveAs(filePath);
// Delete old file - update action
if (!string.IsNullOrEmpty(currentFile))
{
string oldFilePath = Server.MapPath($"~/Upload/{currentFile}");
System.IO.File.Delete(oldFilePath);
}
return imageId;
}
return currentFile;
}
}
Model:
public class SERVICESmodel
{
public int ID { get; set; }
[Required]
public int CAT_ID { get; set; }
[Required]
[Display(Name = "Category")]
public string catName { get; set; }
[Required]
public int TYP_ID { get; set; }
[Required]
[Display(Name = "User")]
public string typName { get; set; }
[Required]
public int CLASS_ID { get; set; }
[Required]
[Display(Name = "CLASS")]
public string ClassName { get; set; }
[Required]
public int LEVEL_ID { get; set; }
[Required]
[Display(Name = "LEVEL")]
public string levelName { get; set; }
[Required]
public int CHANNEL_ID { get; set; }
[Required]
[Display(Name = "CHANNE")]
public string channelName { get; set; }
[Required]
[Display(Name = "NAME")]
public string NAME { get; set; }
[Required]
[Display(Name = "DESC")]
public string DESC { get; set; }
public bool SRVC_FEES { get; set; }
[Url(ErrorMessage = "Please, enter correct url!")]
public string SRVC_LINK { get; set; }
public bool SRVC_STS { get; set; }
public System.DateTime CREATED_DATE { get; set; }
public System.DateTime MODIFY_DATE { get; set; }
public string MANUAL { get; set; }
public HttpPostedFileBase MANUALfile { get; set; }
public SelectList Categories { get; set; }
public SelectList UserType { get; set; }
public SelectList Level { get; set; }
public SelectList Channel { get; set; }
public SelectList Class { get; set; }
}
public class ServiceListModel
{
public IEnumerable<SERVICESmodel> SERVICEs { get; set; }
public string Query { get; set; }
[Display(Name = "Category")]
public int CATID { get; set; }
[Display(Name = "User")]
public int TYPID { get; set; }
[Display(Name = "CLASS")]
public int CLASSID { get; set; }
[Display(Name = "LEVEL")]
public int LEVELID { get; set; }
[Display(Name = "CHANNEL")]
public int CHANNELID { get; set; }
public SelectList Categories { get; set; }
public SelectList UserType { get; set; }
public SelectList Class { get; set; }
public SelectList Level { get; set; }
public SelectList Channel { get; set; }
}
AutoMapper:
public static class AutoMapperConfig
{
public static IMapper Mapper { get; private set; }
public static void Init()
{
var config = new MapperConfiguration(cfg =>
{
//category mapper
cfg.CreateMap<CATEGORy, CATEGORIESmodel>()
.ForMember(dst => dst.ID, src => src.MapFrom(e => e.ID))
.ForMember(dst => dst.NAME, src => src.MapFrom(e => e.CAT_NAME))
.ReverseMap();
// classification mapper
cfg.CreateMap<CALSSIFICATION, CALSSIFICATIONmodel>()
.ForMember(dst => dst.ID, src => src.MapFrom(e => e.ID))
.ForMember(dst => dst.NAME, src => src.MapFrom(e => e.CLASS_NAME))
.ReverseMap();
//channel mapper
cfg.CreateMap<CHANNEL, CHANNELSmodel>()
.ForMember(dst => dst.ID, src => src.MapFrom(e => e.ID))
.ForMember(dst => dst.NAME, src => src.MapFrom(e => e.CHANNEL_NAME))
.ReverseMap();
//MATURITY_LEVEL mapper
cfg.CreateMap<MATURITY_LEVEL, MATURITY_LEVELmodel>()
.ForMember(dst => dst.ID, src => src.MapFrom(e => e.ID))
.ForMember(dst => dst.NAME, src => src.MapFrom(e => e.LEVEL_NAME))
.ReverseMap();
//user_type mapper
cfg.CreateMap<USER_TYPE, USER_TYPEmodel>()
.ForMember(dst => dst.ID, src => src.MapFrom(e => e.ID))
.ForMember(dst => dst.NAME, src => src.MapFrom(e => e.TYP_NAME))
.ReverseMap();
// Services mapper
cfg.CreateMap<SERVICE_ALL, SERVICESmodel>()
.ForMember(dst => dst.ID, src => src.MapFrom(e => e.ID))
.ForMember(dst => dst.catName, src => src.MapFrom(e => e.CATEGORy.CAT_NAME))
.ForMember(dst => dst.typName, src => src.MapFrom(e => e.USER_TYPE.TYP_NAME))
.ForMember(dst => dst.levelName, src => src.MapFrom(e => e.MATURITY_LEVEL.LEVEL_NAME))
.ForMember(dst => dst.ClassName, src => src.MapFrom(e => e.CALSSIFICATION.CLASS_NAME))
.ForMember(dst => dst.channelName, src => src.MapFrom(e => e.CHANNEL.CHANNEL_NAME))
.ForMember(dst => dst.NAME, src => src.MapFrom(e => e.SRVC_NAME))
.ForMember(dst => dst.DESC, src => src.MapFrom(e => e.SRVC_DESC))
.ReverseMap();
});
Mapper = config.CreateMapper();
}
}
Service Interface:
public interface IServices1
{
int Create(SERVICE_ALL service);
List<SERVICE_ALL> ReadAll
(string query = null,
int ? CATID = null,
int? TYPID = null,
int? CLASSID= null,
int? LEVELID = null , int? CHANNELID =null);
SERVICE_ALL Get(int Id);
}
public class Services1 : IServices1
{
private readonly EservicesEntities1 db;
public Services1()
{
db = new EservicesEntities1();
}
public int Create(SERVICE_ALL service)
{
service.CREATED_DATE = DateTime.Now;
db.SERVICE_ALL.Add(service);
return db.SaveChanges();
}
public SERVICE_ALL Get(int Id)
{
return db.SERVICE_ALL.Find(Id);
}
public List<SERVICE_ALL> ReadAll(string query = null,
int? CATID = null,
int? TYPID = null,
int? CLASSID = null,
int? LEVELID = null
,int? CHANNELID = null)
{
return db.SERVICE_ALL.Where(c =>(CATID == null || c.CAT_ID == CATID)
&& (TYPID == null || c.TYP_ID == TYPID)
&&(CLASSID == null || c.CLASS_ID == CLASSID)
&&(LEVELID == null || c.LEVEL_ID == LEVELID)
&&(CHANNELID == null || c.CHANNEL_ID == CHANNELID)
&& (query == null || c.SRVC_NAME.Contains(query))).ToList();
}
}
The relation seams to be find and works with other example but when trying to get with all of the possible Include it fails with the error.
Widget widget = _dbContext.Widgets.Where(w => w.Id == id)
.Include(w => w.DataSource)
.ThenInclude(d => d.DataSourceParams)
.ThenInclude(p => p.DataSourceParamProc)
.ThenInclude(s => s.DataSourceParamProcParams)
.Include(w => w.DataSource)
.ThenInclude(d => d.DataSourceParams)
.ThenInclude(p => p.SelectOptions)
.FirstOrDefault();
POCO's:
public class Widget
{
public int Id { get; set; }
public string Title { get; set; }
public int DataSourceId { get; set; }
public string Colour { get; set; }
public string Icon { get; set; }
public virtual DataSource DataSource { get; set; }
}
public class DataSource
{
public int Id { get; set; }
public string Name { get; set; }
public string Description { get; set; }
public string StoredProc { get; set; }
public string DataBaseName { get; set; }
public virtual ICollection<DataSourceParam> DataSourceParams { get; set; }
}
public class DataSourceParam
{
public int Id { get; set; }
public int DataSourceId { get; set; }
public string Name { get; set; }
public int TypeId { get; set; }
public virtual DataSource DataSource { get; set; }
public virtual DataSourceParamProc DataSourceParamProc { get; set; }
}
public class DataSourceParamProc
{
public int Id { get; set; }
public string StoredProc { get; set; }
public string DataBaseName { get; set; }
[ForeignKey("DataSourceParam")]
public int DataSourceParamId { get; set; }
public virtual DataSourceParam DataSourceParam { get; set; }
public virtual ICollection<DataSourceParamProcParam> DataSourceParamProcParams { get; set; }
}
public class DataSourceParamProcParam
{
public int Id { get; set; }
public string Name { get; set; }
public string DefaultValue { get; set; }
public int DataSourceParamProcId { get; set; }
}
public class SelectOption
{
public int Id { get; set; }
public string Value { get; set; }
public string Label { get; set; }
public int DataSourceParamId { get; set; }
public virtual DataSourceParam DataSourceParam { get; set; }
}
I'm getting error :
A column has been specified more than once in the order by list. Columns in the order by list must be unique.
If I comment this line it works:
Widget widget = _dbContext.Widgets.Where(w => w.Id == id)
.Include(w => w.DataSource)
.ThenInclude(d => d.DataSourceParams)
.ThenInclude(p => p.DataSourceParamProc)
//.ThenInclude(s => s.DataSourceParamProcParams)
.Include(w => w.DataSource)
.ThenInclude(d => d.DataSourceParams)
.ThenInclude(p => p.SelectOptions)
.FirstOrDefault();
Or If I comment this one it works as well:
Widget widget = _dbContext.Widgets.Where(w => w.Id == id)
.Include(w => w.DataSource)
.ThenInclude(d => d.DataSourceParams)
.ThenInclude(p => p.DataSourceParamProc)
.ThenInclude(s => s.DataSourceParamProcParams)
//.Include(w => w.DataSource)
// .ThenInclude(d => d.DataSourceParams)
// .ThenInclude(p => p.SelectOptions)
.FirstOrDefault();
If I separate this it works as well:
Widget widget = _dbContext.Widgets.Where(w => w.Id == id)
.Include(w => w.ChartAttributes)
.ThenInclude(c => c.ChartAttributeType)
.Include(w => w.WidgetCategory)
.Include(w => w.WidgetSeries)
.Include(w => w.WidgetType)
.FirstOrDefault();
DataSource ds = _dbContext.DataSources.Where(d => d.Id == widget.DataSourceId)
.Include(d => d.DataSourceParams)
.ThenInclude(p => p.SelectOptions)
.Include(d => d.DataSourceParams)
.ThenInclude(p => p.DataSourceParamProc)
.ThenInclude(s => s.DataSourceParamProcParams).FirstOrDefault();
widget.DataSource = ds;
I am trying to describe the mapping to EF to create multiple many-to-many relationships between the following two entities (simplified):
Product:
public class Product
{
[Key]
public int ProductID { get; set; }
public string ProductName { get; set; }
public decimal Price { get; set; }
public virtual ICollection<Transaction> Transactions { get; set; }
public virtual ICollection<Transaction> RefundTransactions { get; set; }
public virtual ICollection<Transaction> VoidTransactions { get; set; }
}
Transaction:
public class Transaction
{
[Key]
public int TransactionID { get; set; }
public virtual ICollection<Product> Products { get; set; }
public virtual ICollection<Product> RefundProducts { get; set; }
public virtual ICollection<Product> VoidProducts { get; set; }
}
OnModelCreating:
modelBuilder.Entity<Transaction>()
.HasMany(m => m.Products)
.WithMany(t => t.Transactions)
.Map(m =>
{
m.ToTable("Transaction_Product_Mapping");
m.MapLeftKey("TransactionID");
m.MapRightKey("ProductID");
}
);
modelBuilder.Entity<Transaction>()
.HasMany(transaction => transaction.VoidProducts)
.WithMany(t => t.VoidTransactions)
.Map(m =>
{
m.ToTable("Transaction_Void_Product_Mapping");
m.MapLeftKey("TransactionID");
m.MapRightKey("VoidProductID");
}
);
modelBuilder.Entity<Transaction>()
.HasMany(m => m.RefundProducts)
.WithMany(t => t.Transactions)
.Map(m =>
{
m.ToTable("Transaction_Refund_Product_Mapping");
m.MapLeftKey("TransactionID");
m.MapRightKey("RefundProductID");
}
);
Exception:
Type Transaction_Products is not defined in namespace Nautix_EPOS.Models
Now, I think this may be because I am defining the mapping 3 times separately. And possibly overwriting the first with the second, and the second with the last.
Question:
How can I tell EF about the multiple many-to-many mappings between the same two tables?
I figured it out, it's because I used the same t.Transactions in the first and third declaration. I should have use t.RefundTransactions:
modelBuilder.Entity<Transaction>()
.HasMany(m => m.Products)
.WithMany(t => t.Transactions)
.Map(m =>
{
m.ToTable("Transaction_Product_Mapping");
m.MapLeftKey("TransactionID");
m.MapRightKey("ProductID");
}
);
modelBuilder.Entity<Transaction>()
.HasMany(transaction => transaction.VoidProducts)
.WithMany(t => t.VoidTransactions)
.Map(m =>
{
m.ToTable("Transaction_Void_Product_Mapping");
m.MapLeftKey("TransactionID");
m.MapRightKey("VoidProductID");
}
);
modelBuilder.Entity<Transaction>()
.HasMany(m => m.RefundProducts)
.WithMany(t => t.RefundTransactions)
.Map(m =>
{
m.ToTable("Transaction_Refund_Product_Mapping");
m.MapLeftKey("TransactionID");
m.MapRightKey("RefundProductID");
}
);
I have tried to make an inheritation mapping. There are two
alternative. One alternative is with JoinedSubClass (that is
deprecated and give me a warning) and the other and newer is with
SubClassMap.
But I get an error that I have duplicate entity/object mapping. What
could be the problem?
With the JoinedSubClass it runs. Here are the Codes of my two Objects
and the MappingFile with JoinedSubClass which runs, later there are
the code of my mapping file with "SubClassMap" which doesn't run....
Objects:
public class Person {
public virtual int Id { get; private set; }
public virtual string Vorname { get; set; }
public virtual string Nachname { get; set; }
public virtual string Email { get; set; }
public virtual Adresse Adresse { get; set; }
public Person() {
}
}
public class PersonQuelle : Person, IQuelle {
public virtual string Beschreibung { get; set; }
public virtual Institution Institution { get; set; }
public virtual IList<MediaDatei> MediaDateien { get; set; }
public PersonQuelle() {
MediaDateien = new List<MediaDatei>();
}
public virtual void HinzufuegenMediaDatei(MediaDatei mediaDatei) {
mediaDatei.PersonQuelle = this;
MediaDateien.Add(mediaDatei);
}
public virtual void LoeschenMediaDatei(MediaDatei mediaDatei)
{
mediaDatei.PersonQuelle = null;
MediaDateien.Remove(mediaDatei);
}
}
Mapping Files:
public class PersonMap : ClassMap<Person> {
public PersonMap() {
Id(x => x.Id);
Map(x => x.Vorname);
Map(x => x.Nachname);
Map(x => x.Email);
References(x => x.Adresse);
JoinedSubClass<PersonQuelle>("personQuelle_Id", m => {
m.Map(c => c.Beschreibung);
m.References(c => c.Institution);
m.HasMany(c => c.MediaDateien).Inverse().Cascade.All();
});
JoinedSubClass<MMAdminBenutzer>("mmAdminBenutzer_Id", m =>
{
m.Map(c => c.Kuerzel);
m.Map(c => c.Passwort);
m.Map(c => c.Benutzerrolle);
m.HasMany(c => c.MediaDateien).Inverse().Cascade.All();
m.HasMany(c => c.Kategorien).Inverse().Cascade.All();
});
}
}
But why it doesn't run when I do that with the same Objects however
with this mapping file??
Mapping File with SubClassMap:
public class PersonMap : ClassMap<Person> {
public PersonMap() {
Id(x => x.Id);
Map(x => x.Vorname);
Map(x => x.Nachname);
Map(x => x.Email);
References(x => x.Adresse);
}
}
public class PersonQuelleMap : SubclassMap<PersonQuelle>
{
PersonQuelleMap()
{
Map(c => c.Beschreibung);
References(c => c.Institution);
HasMany(c => c.MediaDateien).Inverse().Cascade.All();
}
}
It's hard to tell without the error that you get, but I think you are missing a call to KeyColumn("personQuelle_Id") in your SubclassMap.