I have view width columns:
ID,
TREE_NODE_ID,
ATTRIB_ID,
INT_VALUE,
DATE_VALUE,
STRING_VALUE,
and table:
ID,
PARENT_ID,
TREE_ID,
public interface ITreeNode
{
long Id { get; set; }
ITreeNode Parent { get; set; }
// I want to get:
IDictionary<IAttribute, IAllTreeNodeValues> SpecTreeNodeValues { get; set; }
}
public interface IAllTreeNodeValues
{
long Id { get; set; }
ITreeNode TreeNode { get; set; }
IAttribute Attribute { get; set; }
long? IntValue { get; set; }
DateTime DateValue { get; set; }
string StringValue { get; set; }
}
fragment of mapping file:
<map name="SpecTreeNodeValues" lazy="true">
<key column="TREE_NODE_ID"/>
<index-many-to-many column="ATTRIB_ID" class="Attribute"/>
<many-to-many class="AllTreeNodeValues"/>
</map>
got an error: An association from the table SpecTreeNodeValues refers to an unmapped class: GeneralData.Entity.Atribute
You misspelled Attribute here:
<index-many-to-many column="ATTRIB_ID" class="Atribute"/>
Related
I am creating a ASP.NET Core web API that uses EF Core. I have a GET endpoint that returns a list of reports from the database. I have a related table which stores screenshots for the reports. The reportId is the foreign key in the images table.
I have a List item in the reports class which points to the ImagesList class.
I have the foreign key reportId in the ImageList class and identified as a foreign key. I also have a navigation property setup to the Reports class.
Reports Class:
[Table("Vw_ReportsList", Schema = "pbi")]
public class Reports
{
[Key]
public string reportId { get; set; }
[Required]
public string reportName { get; set; }
public string reportDescription { get; set; }
public string reportType { get; set; }
public string reportAuthor { get; set; }
public string reportLastUpdate { get; set; }
public string reportLastExecution { get; set; }
public List<ImagesList> Screenshots { get; set; }
//collection navigation property
}
ImageList Class:
[Table("Vw_ScreenshotsList", Schema = "pbi")]
public class ImagesList
{
[Key]
public int id { get; set; }
public string fileNameTest { get; set; }
public string imageData { get; set; }
public string created { get; set; }
public string reportId { get; set; }
[ForeignKey("reportId")]
public virtual Reports Reports { get; set; }
//navigation property
}
Context:
public class ServiceCatalogContext : DbContext
{
public ServiceCatalogContext(DbContextOptions<ServiceCatalogContext> options) : base(options) { }
public DbSet<Reports> Reports { get; set; }
public DbSet<ImagesList> ImagesLists { get; set; }
public DbSet<Images> Images { get; set; }
//used for the image upload POST call
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
// modelBuilder.Entity<ImagesList>().HasOne<Reports>().WithMany().HasForeignKey(s => s.reportId);
modelBuilder.Entity<ImagesList>().HasOne(s => s.Reports).WithMany(s => s.Screenshots).HasForeignKey(s => s.reportId);
modelBuilder.Entity<Reports>().HasMany(r => r.Screenshots).WithOne().HasForeignKey(r => r.reportId);
}
}
My API works and returns the list of reports with no errors but I do not receive the screenshots list that I am expecting.
Here is a sample of the API output:
{
"reportId": "AC79F4CD-3771-42B2-B7F8-46AE4CE8DC80",
"reportName": "Dashboard Usage Metrics Report",
"reportDescription": "DESCRIPTION HERE - Dashboard Usage Metrics Report",
"reportType": "Excel",
"reportLastUpdate": "07/22/2020",
"reportLastExecution": "07/23/2020"
},
{
"reportId": "138CD5FA-6B5A-4C63-A449-DA9A9BBBF689",
"reportName": "Report Usage Metrics Report",
"reportDescription": "DESCRIPTION HERE - Report Usage Metrics Report",
"reportType": "Excel",
"reportLastUpdate": "07/22/2020",
"reportLastExecution": "07/23/2020"
}
I not receiving any error message from the API so I am not sure what I missed in order for each report to return the related images.
Edit: Adding Controller action
[HttpGet]
[EnableQuery()] //enabled OData querying
public IQueryable<Reports> Get()
{
return _context.Reports;
}
Edit: Updated ImagesList class
I also have Odata installed so here the metadata if that is of help:
<?xml version="1.0" encoding="utf-8"?>
<edmx:Edmx Version="4.0" xmlns:edmx="http://docs.oasis-open.org/odata/ns/edmx">
<edmx:DataServices>
<Schema Namespace="ServiceCatalog.API.Entities" xmlns="http://docs.oasis-open.org/odata/ns/edm">
<EntityType Name="Reports">
<Key>
<PropertyRef Name="reportId" />
</Key>
<Property Name="reportId" Type="Edm.String" Nullable="false" />
<Property Name="reportName" Type="Edm.String" Nullable="false" />
<Property Name="reportDescription" Type="Edm.String" />
<Property Name="reportType" Type="Edm.String" />
<Property Name="reportLastUpdate" Type="Edm.String" />
<Property Name="reportLastExecution" Type="Edm.String" />
<NavigationProperty Name="Screenshots" Type="Collection(ServiceCatalog.API.Entities.ImagesList)" />
</EntityType>
<EntityType Name="ImagesList">
<Key>
<PropertyRef Name="id" />
</Key>
<Property Name="id" Type="Edm.Int32" Nullable="false" />
<Property Name="fileNameTest" Type="Edm.String" />
<Property Name="imageData" Type="Edm.String" />
<Property Name="created" Type="Edm.String" />
<Property Name="reportId" Type="Edm.String" />
<NavigationProperty Name="Reports" Type="ServiceCatalog.API.Entities.Reports">
<ReferentialConstraint Property="reportId" ReferencedProperty="reportId" />
</NavigationProperty>
</EntityType>
</Schema>
<Schema Namespace="Default" xmlns="http://docs.oasis-open.org/odata/ns/edm">
<EntityContainer Name="Container">
<EntitySet Name="reports" EntityType="ServiceCatalog.API.Entities.Reports" />
</EntityContainer>
</Schema>
</edmx:DataServices>
</edmx:Edmx>
Design your model like below:
[Table("Vw_ReportsList", Schema = "pbi")]
public class Reports
{
[Key]
public string reportId { get; set; }
[Required]
public string reportName { get; set; }
public string reportDescription { get; set; }
public string reportType { get; set; }
public string reportAuthor { get; set; }
public string reportLastUpdate { get; set; }
public string reportLastExecution { get; set; }
public List<ImagesList> Screenshots { get; set; }
//collection navigation property
}
[Table("Vw_ScreenshotsList", Schema = "pbi")]
public class ImagesList
{
[Key]
public int id { get; set; }
public string fileNameTest { get; set; }
public string imageData { get; set; }
public string created { get; set; }
public string reportId { get; set; }
// [ForeignKey("reportId")]
public virtual Reports Reports { get; set; }
//navigation property
}
And your DbContext:
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<ImagesList>().HasOne(s => s.Reports)
.WithMany(s => s.Screenshots).HasForeignKey(s => s.reportId);
//modelBuilder.Entity<Reports>().HasMany(r => r.Screenshots).WithOne().HasForeignKey(r => r.reportId);
}
Your controller:
[HttpGet]
public IQueryable<Reports> Get()
{
return _context.Reports.Include(r=>r.Screenshots);
}
Be sure to install Microsoft.AspNetCore.Mvc.NewtonsoftJson then use the following code:
services.AddControllers().AddNewtonsoftJson(options =>
{
options.SerializerSettings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;
});
namespace ServExchange.Model
{
public class ApplicationUser : IdentityUser
{
public string Address { get; set; }
public string Name { get; set; }
public string ProfileSummary { get; set; }
public string PhotoPath { get; set; }
public virtual ICollection<Product> Products { get; set; }
}
Below is the Product Class with the ApplicationUser Id as foreign Key.
public class Product
{
[Key]
public int Id { get; set; }
[Required]
public string Name { get; set; }
[Required]
public string Description { get; set; }
[Required]
[Column(TypeName = "decimal(18,2)")]
public decimal Price { get; set; }
[Required]
public int MinQuantity { get; set; }
public virtual ApplicationUser ApplicationUser { get; set; }
}
How do I reference the Product to the ApplicationUser in a view?
You can directly query the database in controller and pass the list to view :
if (User.Identity.IsAuthenticated)
{
var result= _applicationDbContext.Products.Where(x => x.ApplicationUser.Id == User.FindFirstValue(ClaimTypes.NameIdentifier)).ToList();
}
In ApplicationDbContext, add the DbSet and apply migration :
public DbSet<Product> Products { get; set; }
I was making an API for saving a model where it has one to many relationship with another model. When I applying automapping in it. it is giving me following error:
CreateContestDto -> Contest
tritronAPI.DTOs.CreateContestDto -> tritronAPI.Model.Contest
Type Map configuration:
CreateContestDto -> Contest
tritronAPI.DTOs.CreateContestDto -> tritronAPI.Model.Contest
Destination Member:
Problems
---> AutoMapper.AutoMapperMappingException: Missing type map
configuration or unsupported mapping.
Mapping types:
ProblemDto -> Problem
tritronAPI.DTOs.ProblemDto -> tritronAPI.Model.Problem
at lambda_method(Closure , ProblemDto , Problem , ResolutionContext )
My models are: Contest and Problem a contest contain many problems:
public class Contest
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int Id { get; set; }
public string Name { get; set; }
public DateTime StartTime { get; set; }
public DateTime EndTime { get; set; }
public ICollection<Problem> Problems { get; set; }
public ICollection<ContestProgrammingLanguage>
ContestProgrammingLanguages { get; set; }
}
public class Problem
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int Id { get; set; }
[Required]
[MaxLength(255)]
public string ProblemName { get; set; }
[ForeignKey("User")]
public string ProblemAuthorId { get; set; }
public virtual User ProblemAuthor { get; set; }
public string AuthorName { get; set; }
//public virtual List<Resources> Resourceses { get; set; }
public string ProblemDescription { get; set; }
public bool IsPublished { get; set; }
public virtual ICollection<Submission> Submissions { get; set; }
public string Tags { get; set; }
//public Guid Contest_Id { get; set; }
public virtual Contest Contest { get; set; }
[ForeignKey("Contest")]
public int? Contest_Id { get; set; }
public short Score { get; set; }
//Timelimit in miliseconds
public int TimeLimit { get; set; }
//MemoryLimit in bytes
public int MemoryLimit { get; set; }
//More than source code limit is not allowed
public int? SourceCodeLimit { get; set; }
public virtual ICollection<TestFile> TestFiles { get; set; } = new
List<TestFile>();
}
public class CreateContestDto
{
public CreateContestDto()
{
this.Problems = new HashSet<ProblemDto>();
}
public string Name { get; set; }
public DateTime StartDate { get; set; }
public DateTime StartTime { get; set; }
public DateTime EndDate { get; set; }
public DateTime EndTime { get; set; }
public string BackgroundImage { get; set; }
public string Description { get; set; }
public ICollection<ProblemDto> Problems { get; set; }
}
public class ProblemDto
{
public int Id { get; set; }
public string ProblemName { get; set; }
}
mapping profile:
CreateMap<CreateContestDto, Contest>().ForMember(
dest => dest.Problems , opt => opt.MapFrom(src =>
src.Problems));
controller code:
public async Task<IActionResult> AddContest([FromBody]
CreateContestDto contest)
{
var con = _mapper.Map<Contest>(contest);
this._uow.ContestRepository.Add(con);
return Ok();
}
I have already tried with reversemap selecting new id in mapping profile
You also need to add mappings for ProblemDTO to Problem:
CreateMap<CreateContestDto, Contest>();
CreateMap<ProblemDto, Problem>();
In our businessslogic we have some contacts row that may have a relationship with one billing row (0..N).
Here the contact class
public class ESUsersContact
{
[Key]
public int Id { get; set; }
[ForeignKey("Billing")]
public int? BillingId { get; set; }
public string Title { get; set; }
public string Name { get; set; }
public string Address { get; set; }
public string Email { get; set; }
public string City { get; set; }
public string PostalCode { get; set; }
public string Phone { get; set; }
public string CellPhone { get; set; }
public string Fax { get; set; }
public ES.Enums.BusinessESCommon.Language.AllLanguage Language { get; set; }
public virtual ICollection<ESUsersCompany> Companies { get; set; }
public virtual ESUsersBilling Billing { get; set; }
}
Here is the billing class
[Key, Column(Order = 0)]
[ForeignKey("Company")]
public int CompanyId { get; set; }
[Key, Column(Order = 1)]
public ES.Enums.BusinessESUsers.Billing.Type Type { get; set; }
public ES.Enums.BusinessESUsers.Billing.Payment PaymentType { get; set; }
public ES.Enums.BusinessESUsers.Billing.Frequency PaymentFrequency { get; set; }
public decimal Amount { get; set; }
public bool IsFreeTrial { get; set; }
public DateTime FreeTrialEndDate { get; set; }
public DateTime? NextPaymentDate { get; set; }
public virtual ESUsersCompany Company { get; set; }
public virtual ICollection<ESUsersContact> Contacts { get; set; }
}
However, I receive this error doing so.
The relationship from 'ESUsersContact.Billing' to 'ESUsersBilling.Contacts' with foreign key properties {'BillingId' : Nullable<int>} cannot target the primary key {'CompanyId' : int, 'Type' : Type} because it is not compatible. Configure a principal key or a set of compatible foreign key properties for this relationship.
I don't understand why the error occurs and state the primary key {'CompanyId' : int, 'Type' : Type}.
ESUsersContact.Billing class has a composite key. ESUsersContact has to map both of the foreign keys. CompanyId and Type. You can not refer only one column since ESUsersContact.Billing has two columns for the key.
I have the following database schema:
http://lh4.ggpht.com/_SDci0Pf3tzU/SdM3XnAmmxI/AAAAAAAAEps/Ie3xW3ZVNfQ/styleerror.png
The issue is how to create the entity data class in Nhibernate?
Is this better:
public class Store
{
public virtual int Id { get; private set; }
public virtual string Name { get; set; }
public virtual IList<Product> Products { get; set; }
public virtual IList<Employee> Staff { get; set; }
}
public class Employee
{
public virtual int Id { get; private set; }
public virtual string FirstName { get; set; }
public virtual string LastName { get; set; }
public virtual Store Store { get; set; }
}
public class Product
{
public virtual int Id { get; private set; }
public virtual string Name { get; set; }
public virtual double Price { get; set; }
public virtual IList<Store> StoresStockedIn { get; private set; }
}
Or is this better?
public class Store
{
public virtual int Id { get; private set; }
public virtual string Name { get; set; }
}
public class Employee
{
public virtual int Id { get; private set; }
public virtual string FirstName { get; set; }
public virtual string LastName { get; set; }
public virtual Store Store { get; set; }
}
public class Product
{
public virtual int Id { get; private set; }
public virtual string Name { get; set; }
public virtual double Price { get; set; }
}
public class StoreProduct
{
public virtual List<Product> Products{get;set;}
public virtual List<Store> Stores{get;set;};
}
I think the first one is easier to understand than the second, isn't it?
If you modify the 'StoreProduct' table, so that it has no surrogate primary key, but a primary key which exists of the 2 foreign key columns (ProductId & StoreId), then you can simply limit yourself to 3 entities:
- Employee
- Product
- Store
Your Store class could then have a Set of Products, which can simply be mapped as a many-to-many relationship.
public class Store
{
public int Id {get;set;}
public string Name {get;set;}
public ISet<Product> Products = new HashedSet<Product>();
}
And in the Store.hbm.xml mapping:
<set name="Products" table="StoreProducts">
<key column="Store_Id" />
<many-to-many class="Product" column="Product_Id" />
</set>
So, to answer your question: first option is better.