This has been puzzling me for quite some time but I keep getting an invalid identifier error when my entity framework tries to execute an oracle query. The classes in question are the following:
public class Projectship : ModelTrackingBase
{
[Column("PROJECTID")]
public long ProjectId { get; set; }
[Column("VISITID")]
public long VisitId { get; set; }
public virtual Bpid Bpid { get; set; } //new
public virtual Visit Visit { get; set; }
}
and
public class Bpid : EntityIdBase
{
[Column("BUDPRJID")]
[MaxLength(38)]
public string BPId { get; set; }
[Column("DESCRIPTION")]
[MaxLength(255)]
public string Description { get; set; }
[Column("CSTOBJ")]
[MaxLength(255)]
public string Custobj { get; set; }
[Column("PVID")]
[MaxLength(255)]
public string Pvid { get; set; }
public virtual ICollection<Projectship> Projectships { get; set; }
public IEnumerable<Visit> Visits
{
get { return Projectships.Select(p => p.Visit); }
}
[NotMapped]
public string DisplayName
{
get { return string.Format("{0}: {1}", BPId , Description); }
}
}
Now the EntityIdBase has the following:
public class EntityIdBase : EntityBase
{
[Column("ID")]
public long Id { get; set; }
}
It tries to keep on looking for a column Bpid_Id in the query. Does someone have any idea?
Bpid_id is created by EF because it can't automatically determine the relationship. Try adding the annotation:
[ForeignKey("ID")]
public virtual Bpid Bpid { get; set; } //new
You have specified a navigation property in the Projectship class
public virtual Bpid Bpid { get; set; }
You have not specified a foreign key to go with the navigation property so Entity Framework has chosen one, and it has chosen the name Bpid_Id. And it should be in the database. It should not be "non-existent".
You will probably find it easier to use Entity Framework if you add a foreign key like this:
public int BpidId { get; set; }
References:
Why does Entity Framework Reinsert Existing Objects into My Database?
Making Do with Absent Foreign Keys
Related
I'm trying to think of a way to store actual templates of ticket items in my Entity Framework MVC project. The thing is, I've already done a Code First migration process in the past. What I need to do is create logic in my code to allow someone to save time creating a ticket by using pre-loaded data from a template. My current inheritance model uses an abstract class (MasterTicket) which is used as the parent since to me there can be multiple categories (a Google Calendar based task, "Appointment Task" and a purely internal task, "General Task"). Here's my parent abstract class:
[Table("Ticket")]
[ModelBinder(typeof(MasterTicketBinder))]
public abstract class MasterTicket
{
[Key]
public Guid id{ get; set; }
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int ART { get; set; }
public DateTime openTime{ get; set; }
public DateTime? closeTime { get; set; }
private bool active = true;
public bool Active{ get => active; set => active = value; }
public string summary{ get; set; }
public string description{ get; set; }
public DateTime updateTime{ get; set; }
//TODO: Create foreign key relationship to user model
public Guid userUpdateId{ get; set; }
//TODO: Create foreign key relationship for tickets from other systems
public Guid externalAppId{ get; set; }
//TODO: Create foreign key relationship to user model
public Guid userOpenId{ get; set; }
public Guid? userCloseId { get; set; }
public Guid userOwnerId{ get; set; }
private int timesUpdated = 0;
public int TimesUpdated { get => timesUpdated; set => timesUpdated = value; }
public DateTime expectedCompletionTime{ get; set; }
public DateTime actualCompletionTime{ get; set; }
public List<MasterTicketItem> masterTicketItems{ get; set; }
public MasterTicket()
{
}
}
An here's an example of the concrete Google Calendar-based "Appointment Task" child:
[Table("AppointmentTickets")]
public class ApptTaskTicket : MasterTicket
{
public DateTime currentApptTime { get; set; }
public DateTime? endApptTime { get; set; }
public bool allDay { get; set; }
public string customerName { get; set; }
//TODO: Create foreign relationship
public Guid subjectPrsnlId { get; set; }
public string gCalEventId { get; set; }
public string customerPhone { get; set; }
public string customerEmail { get; set; }
public string preferredContactMethod { get; set; }
public List<ApptConfirmItem> apptConfirmItems { get; set; }
}
I know I can easily create a column for the MasterTicket class to indicate that it's a template, but to me I feel it's cleaner to have a separate "Template Table" if you will that will store pre-existing values that can be filled in with a form. In this case, I think I would WANT to create a duplicate class that would store said templates so that there are only several rows. What would be the best way to do this with Code First? Does someone feel I should take a different approach? Maybe DB First is a better way to go?
In case it matters, here's my DBContext for the Tickets:
// Code-Based Configuration and Dependency resolution
[DbConfigurationType(typeof(MySqlEFConfiguration))]
public class TicketDB : DbContext
{
public TicketDB(): base("AffirmativeServiceSystem.Properties.Settings.AffirmTaskManager")
{
}
public DbSet<MasterTicket> tickets { get; set; }
public DbSet<MasterTicketItem> ticketItems { get; set; }
}
Hi I have problem with EF Core insert entity. The problem is that I need to insert new entity with relation to another one which is already existing. I have created the relations with fluent API. I have done this for two times. First I am creating car and adding the last edited by field with Identity user and all works but when I am trying to do the same with another entity it crashes down with
My fluent APi code which works good:
builder.Entity<Car>()
.HasOne(x => x.Owner)
.WithMany(x => x.OwnerCars)
.HasForeignKey(x => x.OwnerId);
Here is car entity:
public class Car : CarBase
{
[Key]
public int CarId { get; set; }
public bool IsTrailer { get; set; }
public virtual TrailerType TrailerType { get; set; }
public virtual int? TrailerTypeId { get; set; }
public virtual ApplicationUser Owner { get; set; }
public virtual string OwnerId { get; set; }
}
and here is Application user entity
public class ApplicationUser : IdentityUser
{
[MaxLength(100)]
public string Address { get; set; }
public DateTime CreatedDateTime { get; set; }
public DateTime LastEditationDateTime { get; set; }
public virtual ApplicationUser LastEditedBy { get; set; }
public bool IsDeleted { get; set; }
public virtual DateTime DeletedDateTime { get; set; }
public ICollection<DriverLicenseApplicationUser> DriverLicenses { get; set; }
public ICollection<RideApplicationUser> Rides { get; set; }
public ICollection<Car> OwnerCars { get; set; }
public ICollection<Car> EditedCars { get; set; }
public ICollection<Trailer> EditedTrailers { get; set; }
public ICollection<Customer> EditedCustomers { get; set; }
}
To add this entity I only call this function and all works.
public Car CreateCar(Car car)
{
_context.Cars.Add(car);
return car;
}
But when I want to save this way this another entity type it shows an error. All steps are same so I do not understand this. Here I am adding the code I use to do that.
builder.Entity<Trailer>()
.HasOne(x => x.TrailerType)
.WithMany(x => x.Trailers)
.HasForeignKey(x => x.TrailerTypeId);
Here is Trailer:
public class Trailer : CarBase
{
[Key]
public int TrailerId { get; set; }
//[Required]
public virtual TrailerType TrailerType { get; set; }
public virtual int TrailerTypeId { get; set; }
}
and here is traylerTyper:
public class TrailerType:Trackable
{
//[Key]
public int TrailerTypeId { get; set; }
[MaxLength(100)]
[Required]
public string Type { get; set; }
public string Note { get; set; }
public ICollection<Car> TrailerTypeCars { get; set; }
public ICollection<Trailer> Trailers{ get; set; }
}
and the method is the same as the one already mentioned
public Trailer CreateTrailer(Trailer trailer)
{
trailer.TrailerTypeId = trailer.TrailerType.TrailerTypeId;
//_context.Attach(trailer.TrailerType);
var result = _context.Trailers.Add(trailer);
return result.Entity;
}
When I uncomment the attach it works but I think that I dont have to attach this because I have got the relation based on IDs and the example mentioned first works great. It gives me no sense. So if anyone could give me advice it would be awsome.
Here is the error I am getting:
Cannot insert explicit value for identity column in table 'TrailerTypes' when IDENTITY_INSERT is set to OFF.
It looks like the EF doesnt know that the traylertype entity already exists and is trying to insert the same entity again and the app crashes because it already exists and I am not allowing to insert IDs directly. As I said I have absolutely no idea why is this happening.
The problem is Lazy loading. Propetry from ViewModel is not completly same as property in Database and EF tracks whole graph of property in object and doesn´t recognize that it is the same object. The solution is to work only with IDs instead with whole objects.
Forewarning: I know approximately nothing when it comes to MVC/Entity Framework/Linq queries.
I'm having an issue when I try to query the database. Here's the query I'm using:
int? UserId = db.StudentModel
.Where(c => c.UserName == certUserName)
.Select(c => c.UserId)
.FirstOrDefault();
When it searches the database, it successfully retrieves the UserId.
The problem is that I then use the following query:
CompletionsModel student = db.Completions.Find(UserId);
When I do this, it throws an inner exception that states
{"Invalid column name 'UserProfile_UserId'."}
The weird thing is that when I go to my code and mouse over the 'db' part of the command to see what data it's holding, it has CourseModel, StudentModel, and Completions (though the model's actual filename is CompletionsModel - is that a clue?), so it seems like they're linked properly.
Here's the code for my three models and the database context.
CompletionsModel (UserProfile is white text in my code; not sure why it's teal here Same with UserId and CompletionDate):
[Table("Completion")]
public class CompletionsModel
{
[Key]
public int UserId { get; set; }
public string PRD_NUM { get; set; }
public DateTime CompletionDate { get; set; }
public virtual CourseModel PRD { get; set; }
public virtual StudentModel UserProfile { get; set; }
}
CourseModel:
[Table("PRD")]
public class CourseModel
{
[Key]
public string PRD_NUM { get; set; }
public string PRD_TIT { get; set; }
//because any number of students can be enrolled in one course
public virtual ICollection<CompletionsModel> CompletionsModel { get; set; }
}
StudentModel:
[Table("UserProfile")]
public class StudentModel
{
[Key]
public int UserId { get; set; }
public string UserName { get; set; }
public virtual ICollection<CompletionsModel> CompletionsModel { get; set; }
}
DBContext:
public class ClassContext : DbContext
{
public ClassContext()
: base("DefaultConnection")
{
}
public DbSet<StudentModel> StudentModel { get; set; }
public DbSet<CompletionsModel> Completions { get; set; }
public DbSet<CourseModel> CourseModel { get; set; }
}
And finally, an image of my database layout - maybe this will help things along, too:
I'm too at the beginning of Entity Framework, but what does irritate me is, that you have kind of foreign key relationship between Completion and UserProfile, without really defining, a int column as foreign key in your Completion Table.
You could try to change
public virtual StudentModel UserProfile { get; set; }
to something like
public virtual int StudentId { get; set; }
[ForeignKey("StudentId")]
public virtual StudentModel UserProfile { get; set; }
The same for PRD
But maybe a change in your database is not what you want.
What you could also do, is to remove these lines
public virtual CourseModel PRD { get; set; }
public virtual StudentModel UserProfile { get; set; }
Hope that helps.
EDIT:
I guess the problem is, that you are missing the ForeignKey Attribute at your UserProfile property in your Completions table.
So use
[ForeignKey("UserId")]
public virtual StudentModel UserProfile { get; set; }
instead of
public virtual StudentModel UserProfile { get; set; }
if the UserIds are representing the same user
I've noticed an issue with EF 6.1 code first. I have the following classes -
namespace Domain
{
public interface ISupportsOptimisticConcurrency
{
byte[] RowVersion { get; set; }
}
public class Entity : ISupportsOptimisticConcurrency
{
public int Id { get; set; }
[Timestamp]
public byte[] RowVersion { get; set; }
}
public class Lookup : Entity
{
public Lookup()
{
Description = string.Empty;
}
[Required]
[MaxLength(100)]
public string Name { get; set; }
[MaxLength(300)]
public string Description { get; set; }
}
public class GroupType : Lookup
{
}
public class Group:Entity
{
public Group()
{
GroupType = new GroupType();
}
[Required]
public string Name { get; set; }
[Required]
public Guid ExternalId { get; set; }
[Required]
public string Password { get; set; }
[Required]
public string MonitorEmail { get; set; }
public string UrlRequestEmail { get; set; }
public bool UsesDefaultOptions { get; set; }
[ForeignKey("GroupType")]
public int GroupTypeId { get; set; }
public virtual GroupType GroupType { get; set; }
}
}
I've written a typical Repository class for accessing data from DB. Now, when I try to find a Group by Id, and include the GroupType, the GroupType doesn't load properly, and the Name property of GroupType comes as null.
Interestingly, when I removed the Group constructor which initializes a new GroupType, things start working fine.
Could you please explain this behavior?
Note: This same scenario works fine with NHibernate as it is.
Thanks for the replies.
I think you have to remove the initialization logic in the Group constructor:
GroupType = new GroupType();
This probably overwrites the loaded data or does not even load it (because it already was instantiated), causing the GroupType property to be the instance that you initialized it with instead of the one in the database.
It may be the same issue as explained here.
Is it possible to have a foreign key mapping based on a specific column value.
I have the following entities.
public class Controller
{
[Key]
public int Id { get; set; }
public string Name { get; set; }
public virtual List<ControllerDevice> ActiveDevices { get; set; }
public virtual List<ControllerDevice> TamperedDevices { get; set; }
public virtual List<ControllerDevice> IgnoredDevices { get; set; }
}
public class ControllerDevice
{
public int Id { get; set; }
public DeviceStatus Status { get; set; }
public int ControllerId { get; set; }
public int NetworkDeviceId { get; set; }
public virtual Controller Controller { get; set; }
public virtual NetowkDevice NetowkDevice { get; set; }
}
public class NetowkDevice
{
[Key]
public int Id { get; set; }
public string Name { get; set; }
}
public enum DeviceStatus
{
Active,
Tampered,
Ignored
}
Is it possible to have the ActiveDevices, TamperedDevices and IngoredDevices list be auto populated based on ControllerDevice DeviceStatus, or would I have to create three different tables for each list. IE ActiveControllerDevice, TamperedControllerDevices and IgnoredControllerDevices.
Please let me know if you require further explanation.
Use single devices collection:
public class Controller
{
[Key]
public int Id { get; set; }
public string Name { get; set; }
public virtual List<ControllerDevice> Devices { get; set; }
}
...and filter it, when you need to process or display devices with specific Status value:
controller.Devices.Where(d => d.Status == DeviceStatus.Active);
Several tables for each devices status, and/or devices hierarchy (theoretically, you can solve this problem with a TPH inheritance) is a way to hell, because instead of single entity ControllerDevice with a status you'll get three entity types (ActiveControllerDevice, TamperedControllerDevice and IgnoredControllerDevice), which is not corresponding to model.
Instead of changing status, the device will change its type, and you cannot do that in simple way.
public class TestContext : DbContext
{
public TestContext()
{
Configuration.AutoDetectChangesEnabled = true;
Configuration.LazyLoadingEnabled = true;
Configuration.ProxyCreationEnabled = true;
Configuration.ValidateOnSaveEnabled = true;
}
public virtual DbSet<NetowkDevice> NetowkDevices{ get; set; }
public virtual DbSet<ControllerDevice> ControllerDevices{ get; set; }
public virtual DbSet<Controller> Controlleres{ get; set; }
}
http://social.msdn.microsoft.com/Forums/en-US/adodotnetentityframework/thread/d0443029-2175-4bde-a834-4f8dbf313201/
Should I enable or disable dynamic proxies with entity framework 4.1 and MVC3?
Yes, you can do that. Enum support was introduced in Entity Framework 5, .Net Framework 4.5. In Entity Framework, an enumeration can have the following underlying types: Byte, Int16, Int32, Int64 , or SByte.
And you can filter like this:
context.ControllerDevices.Where(d => d.Status == DeviceStatus.Active);
More here: http://msdn.microsoft.com/en-us/data/hh859576.aspx