I am using EF 6 in Visual Studio 2013. I want to get matching records from a Parent table on behalf of foreign key from Child table.
I have following line of code
var record = db.ChannelFees.Include(x =>x.SubSource).ToList();
Here ChannelFees is the child table in which SubSourceId is foreign key from
SubSource(Parent Table).
Channel Fee Class Looks Like:
using System;
using System.Collections.Generic;
public partial class ChannelFee
{
public virtual SubSource SubSource { get; set; }
public int SubSource_id { get; set; }
public double Fee { get; set; }
public int Id { get; set; }
}
and the SubSource Class
using System;
using System.Collections.Generic;
public partial class SubSource
{
public int Id { get; set; }
public string Description { get; set; }
public string MapName { get; set; }
}
But I am getting the following exception.
A specified Include path is not valid. The EntityType 'FinancialManagmentModel.ChannelFee' does not declare a navigation property with the name 'SubSource'.
What is wrong with it?
I think it should be:
public virtual ICollection<SubSource> SubSource;
You could try with this:
public partial class ChannelFee
{
public virtual ICollection<SubSource> SubSource { get; set; } // Just to enable lazy load
public int Id { get; set; }
public string Description { get; set; }
public string MapName { get; set; }
}
public partial class SubSource
{
public int Id { get; set; }
public string Description { get; set; }
public string MapName { get; set; }
public virtual ChannelFee ChannelFee {get; set; } // Navigation property
}
And usually I also add a Mapping in the context (you can achieve the same result with configuration attributes)
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<SubSource>().HasRequired(t => t.ChannelFee)
.WithMany(t => t.SubSource);
}
Simplest way to solve the problem is to declare a navigation property with the name 'SubSource'. through Annotations
public partial class ChannelFee
{
[ForeignKey("SubSource_id")]
public virtual SubSource SubSource { get; set; }
public int SubSource_id { get; set; }
}
I have resolved the issue at my own. Actually the EF was not generating navigation property in the Model on the behalf of Foreign Key Constraint which I created in SQL, that is why error was occuring.
So I simply deleted the Model and added it again. Problem was solved.
Related
I am using Entity Framework 6 in a project and am having trouble creating a query.
Say my classes are defined like:
public class MyContext : DbContext
{
public MyContext(string connectionString) : base(connectionString)
{
}
public DbSet<EntityXXX> XXXSet { get; set; }
public DbSet<EntityYYY> YYYSet { get; set; }
}
public class EntityXXX
{
public string XXXName { get; set; }
public int id { get; set; }
public int YYYid { get; set; }
}
public class EntityYYY
{
public string YYYName { get; set; }
public int id { get; set; }
}
The YYYid property of EntityXXX is the 'id' of the EntityYYY instance that it relates to.
I want to be able to fill a Grid with rows where the first Column is XXXName and the second column is YYYName (from its related EntityYYY), but I can't see how to do this?
I'm sure it's really simple, but I'm new to EF.
You need to put a virtual navigation property on your EntityXXX
public virtual EntityYYY YYY { get; set; }
Then you can do a projection:
db.XXXSet
.Select(x => new { x.XXXName, YYYName = x.YYY.YYYName })
.ToList();
Which will get you the list you need.
I am creating a ASP.net MVC web app and trying to add validation attributes to a ClientsTbl.cs file I have generated from a SQL server using entity framework. I have done scaffolding and created the view and the controller for the Table(Model), but for some reason the scaffold did not recognize the primary key column as a primary key. On top of that it will not let me add attributes in []. I can't even change the field description that appears above the views form text box. How do I do the above in the following class?
namespace Testit.Models
{
using System;
using System.Collections.Generic;
public partial class ClientsTbl
{
public ClientsTbl()
{
this.ProgramClientTbls = new HashSet<ProgramClientTbl>();
}
public int id { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public int CenterId { get; set; }
public string MiddleName1 { get; set; }
public string MiddleName2 { get; set; }
public System.DateTime DateAdded { get; set; }
public virtual CenterTbl CenterTbl { get; set; }
public virtual ICollection<ProgramClientTbl> ProgramClientTbls { get; set; }
}
}
You can create a metadata class to do that. For example, if Id, FirstName, and LastName are required fields, you can create a new class like below.
public class ClientsTblMetadata
{
[Required()]
public int Id { get; set; }
[Required()]
public string FirstName { get; set; }
[Required()]
public string LastName { get; set; }
}
Then you need to add a new partial class with a MetadataType attribute. Please make sure that this class is located under the same namespace, otherwise it won't work.
namespace Testit.Models
{
[MetadataType(typeof(ClientsTblMetadata))] // you need this line of code.
public partial class ClientsTbl
I am pulling from an entity object and trying to map to a model. Here is my class information:
// entity class was auto-generated
**public partial class CategoryType
{
public CategoryType()
{
this.OutgoingCategories = new HashSet<OutgoingCategory>();
}
public int CategoryTypeID { get; set; }
public string Name { get; set; }
public string Icon { get; set; }
public virtual ICollection<OutgoingCategory> OutgoingCategories { get; set; }
}**
public class CategoryTypeModel
{
public int CategoryTypeID { get; set; }
public string Name { get; set; }
public string Icon { get; set; }
}
My mapper looks like this:
Mapper.CreateMap<CategoryType, CategoryTypeModel>().ForSourceMember(a => a.OutgoingCategories, o => o.Ignore());
When I go to get the mapped list:
Mapper.Map <List<CategoryType>, List<CategoryTypeModel>>(dbo.CategoryTypes.ToList());
I get the error:
Missing type map configuration or unsupported mapping.
I'm new to using Automapper, so I'm not sure what I'm doing wrong. Any help would be great. Thanks.
Well, I said I was new to Automapper. So.... I guess it would help to call this in my Global.asax:
AutoMapperConfig.Configure();
That solved the problem.
I have a class Employee:
public partial class Employee
{
public Employee()
{
this.Employees1 = new HashSet<Employee>();
}
public int Id { get; set; }
public string Surname { get; set; }
public string Email { get; set; }
public Nullable<int> ReportsToId { get; set; }
public virtual ICollection<Employee> Employees1 { get; set; }
public virtual Employee ReportsTo { get; set; }
}
And a view model for this:
public class EmployeeEditModel : MappedViewModel<Employee>
{
public int Id { get; set; }
public string Surname { get; set; }
public string FirstName { get; set; }
public string Email { get; set; }
public int? ReportsTo { get; set; }
}
MappedViewModel<T> declares a method:
public class MappedViewModel<TEntity>: ViewModel
{
public virtual TEntity MapToEntity()
{
return (TEntity)Mapper.Map(this, GetType(), typeof(TEntity));
}
}
When I call MapToEntity in an action method, as such
I get an exception from AutoMapper with the message:
Missing type map configuration or unsupported mapping.
Mapping types: Int32 -> Employee System.Int32 -> Leave.Data.Employee
Destination path: Employee.ReportsTo.ReportsTo
Source value: 5
My mappings are defined as follows:
public static void RegisterMaps()
{
Mapper.CreateMap<Employee, EmployeeCreateModel>();
Mapper.CreateMap<EmployeeCreateModel, Employee>();
}
The double reference Employee.ReportsTo.ReportsTo screams out to me that this exception is somehow caused by some sort of cyclical mapping quirk, but I what can I do about this? At very least I would like omit ReportsTo from the mapping and simply do this manually after calling MapToEntity. How can I even to this, and rather, what should I do for this pattern of AutoMapper problem?
You need to do more than simple Mapper.CreateMap as it won't magically figured out how to convert between EmployeeViewModel.ReportsTo (int?) and Employee.ReportsTo (Employee).
Either create a mapping between int and Employee or use the ForMember method to tell AutoMapper how to convert the ReportsTo property.
This question is related to this question which was never answered. I have a more real world example here though - so hoping for some help.
I have an auction, bid and auctiondetail(a flattened table) class.
I am trying to include my bids in the auction as well as auctiondetail table, auction and auctiondetail have the same PK
using System.Collections.ObjectModel;
using System.ComponentModel.DataAnnotations;
namespace OnCall.VirtualWarehouse.Data.Models.Auctions
{
using System;
public class AuctionCopy
{
public Guid AuctionCopyId { get; set; }
public virtual Collection<BidCopy> BidCopies { get; set; }
}
public class BidCopy
{
public Guid BidCopyId { get; set; }
public Guid AuctionCopyId { get; set; }
public AuctionCopy AuctionCopy { get; set; }
}
public class AuctionDetailCopy
{
[Key]
public Guid AuctionCopyId { get; set; }
public virtual Collection<BidCopy> BidCopies { get; set; }
}
}
Here's my DBContext:
public class DataContext : DbContext
{
static DataContext()
{
Database.SetInitializer(new DropCreateIfChangeInitializer());
}
public DataContext()
{
Configuration.ProxyCreationEnabled = false;
}
public IDbSet<AuctionCopy> AuctionCopy { get; set; }
public IDbSet<BidCopy> BidCopy { get; set; }
public IDbSet<AuctionDetailCopy> AuctionDetailCopy { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.Conventions.Remove<OneToManyCascadeDeleteConvention>();
}
public void Seed(DataContext context)
{
}
}
When generating the database, I get
The operation failed because an index or statistics with name 'IX_AuctionId' already exists on table 'Bids'.
Any ideas how I can get this to work?
The bug come from EF4.3 (and 4.3.1).
It should be fixed for the next release.
Have a look on Unhandled Exception after Upgrading to Entity Framework 4.3.1. They purpose a workaround using migration system.