Custom Relationship in Entity Framework - c#

I have got the following three tables (just an example)
public class User
{
public int id { get; set; }
public string name { get; set; }
public List<Code> Codes { get; set; }
}
public class Device
{
public int id { get; set; }
public string name { get; set; }
public List<Code> Codes { get; set; }
}
public class Code
{
public int id { get; set; }
public int entity_id { get; set; }
public string entity_type { get; set; }
public string code { get; set; }
}
Now a code can either belong to a User or a Device, which will be determined by the value of entity_type (i.e. 'user' or 'device'). How can this be achieved in Entity Framework ?

You could change your Code class to
public class Code
{
public int id { get; set; }
public User user { get; set; }
public Device device { get; set; }
public string code { get; set; }
}
This way one of those properties can be null.
Hope it helps.
The drawback is that you could have a code that have a user an a device

Related

I got a the entity type requires primary key error

When i try to connect with my database and my class i got this error
But this error appear just for my Consoles,KeyboardMouse and Headphones tables. But they have already primary keys.
and here is my context class
public class EcommContext : DbContext
{
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
optionsBuilder.UseSqlServer(#"Server=.;Database=eCommerce;Trusted_Connection=true");
}
public DbSet<Product> Products { get; set; }
public DbSet<Card> Cards { get; set; }
public DbSet<Category> Categories { get; set; }
public DbSet<Consoles> Consoles { get; set; }
public DbSet<Headphone> Headphones { get; set; }
public DbSet<Order> Orders { get; set; }
public DbSet<OrderDetail> OrderDetails { get; set; }
public DbSet<Mouse> Mouses { get; set; }
public DbSet<MousePad> MousePads { get; set; }
public DbSet<Keyboard> Keyboards { get; set; }
public DbSet<KeyboardAndMouse> KeyboardMouse { get; set; }
public DbSet<Gamepad> Gamepads { get; set; }
public DbSet<Computer> Computers { get; set; }
}
And my entity classes
public class Headphone:IEntity
{
public int HeadphonesId { get; set; }
public int ProductId { get; set; }
public bool IsWireless { get; set; }
public string Type { get; set; }
public string Color { get; set; }
public bool IsGaming { get; set; }
}
public class KeyboardAndMouse:IEntity
{
public int KmId { get; set; }
public int ProductId { get; set; }
public string Color { get; set; }
}
public class Consoles:IEntity
{
public int ConsoleId { get; set; }
public int ProductId { get; set; }
public string Color { get; set; }
public int GamepadNumber { get; set; }
public int Capacity { get; set; }
}
How can I solve that. Does anyone help me ?
In your entity class you need to use [Key] annotation for primary key field. Try like below.
public class Headphone:IEntity
{
[Key]
public int HeadphonesId { get; set; }
}
public class KeyboardAndMouse:IEntity
{
[Key]
public int KmId { get; set; }
}
public class Consoles:IEntity
{
[Key]
public int ConsoleId { get; set; }
}
Please check this out for more information : https://learn.microsoft.com/en-us/ef/core/modeling/keys?tabs=data-annotations#configuring-a-primary-key
FYI - By convention, a property named Id or <type name>Id will be configured as the primary key of an entity.
So if you had HeadphoneId field in Headphone class then it will select that column as primary key by convention and no need to use [Key] annotation or Fluent API to define Primary key field.

How to define a navigation property via Entity Framework code first approach

I have the following class that I want to use as my data context in Entity Framework:
public class AggregateRecord : IAggregateRecord
{
[Key]
public int AggregateRecordID { get; set; }
public DateTime? InsertDate { get; set; } = DateTime.Now;
public DateTime BookingDate { get; set; }
public string AmountTypeName { get; set; }
public int? UnifiedInstrumentCode { get; set; }
public double? Amount { get; set; }
public string BookingAccountID { get; set; }
public string AccountCurrency { get; set; }
public string ClientCurrency { get; set; }
public string AffectsBalance { get; set; }
public string AssetType { get; set; }
public string UnderlyingInstrumentSubType { get; set; }
public string InstrumentSymbol { get; set; }
public string InstrumentSubType { get; set; }
public string UnderlyingInstrumentAssetType { get; set; }
public string UnderlyingInstrumentDescription { get; set; }
public string UnderlyingInstrumentSymbol { get; set; }
public string UnderlyingInstrumentUic { get; set; }
public double? AmountAccountCurrency { get; set; }
public string AmountClientCurrency { get; set; }
public string InstrumentDescription { get; set; }
public virtual ICollection<InstrumentInfo> InstrumentInfo { get; set; }
}
public class InstrumentInfo
{
[Key]
public int InstumentInfoID {get;set;}
public string SomeInformation { get; set; }
public int AggregateRecordID { get; set; }
public virtual AggregateRecord AggregateRecord { get; set; }
}
I have studies the examples provided for EF6 but I still have the problem that when I try to update my migration that I get the following error:
One or more validation errors were detected during model generation:
There are no primary or candidate keys in the referenced table 'dbo.AggregateRecords' that match the referencing column list in the foreign key 'FK_dbo.InstrumentInfoes_dbo.AggregateRecords_AggregateRecordID'.
Could not create constraint or index. See previous errors.
How do I have to define the classes so that InstrumentInfo can be accessed via a navigation property?
public class InstrumentInfo
{
[Key]
public int InstumentInfoID {get;set;}
public string SomeInformation { get; set; }
public int AggregateRecordId { get; set; }
public virtual AggregateRecord AggregateRecord { get; set; }
}
Seems you forgot "public"
I "solved" the problem. It's weird, but maybe it helps somebody in future that's why I answer my own question.
I renamed my class AggregateRecord to AggregateEntry. Performed the Add-Migration and Update-Database, with the new renamed class name. And it worked.
It looks like there was some problem with the migration definition or whatsoever, but it solved it.
In the end, I renamed it back to the original name, did the same procedure again and, voila, it works.
#Dennis Spade: Thanks for your effort, without your hint it would have taken me even more time to find the real "problem".

Reusing models in Web Api

I have a c# class as below
public class CreateStudent
{
public int Id { get; set; }
public string Name { get; set; }
public string Address { get; set; }
public int Age { get; set; }
}
and I need another class with following properties
public class EditStudent
{
public string Name { get; set; }
public string Address { get; set; }
public int Age { get; set; }
public DateTime Date_of_Birth { get; set; }
}
I have repeated properties except that one field (Date_of_Birth) is added in the EditStudent Model.
Is there an option to reuse some of the properties from previous CreateStudent model
I am going to handle these data as Json objects in my front end angularjs based application
You could do this with a null-able property.
public class Student
{
public int Id { get; set; }
public string Name { get; set; }
public string Address { get; set; }
public int Age { get; set; }
public DateTime? Date_of_Birth { get; set; }
}
This way you only have one Student model that can accommodate both use-cases.
you should be using inheritance feature here.
public class CreateStudent
{
public int Id { get; set; }
public string Name { get; set; }
public string Address { get; set; }
public int Age { get; set; }
}
public class EditStudent : CreateStudent
{
public DateTime Date_of_Birth { get; set; }
}

How to show subclass in Report Viewer - VS 2010

I am creating small application where I have done with Business Class. Now, I want to create report.
Firstly, Here is my Property Class :
public class Property
{
public int PropertyId { get; set; }
public int OwnerId { get; set; }
//User is another Class
public User Owner { get; set; }
public int StaffUserId { get; set; }
public Staff StaffPerson { get; set; }
public string Address { get; set; }
public int NoGarage { get; set; }
public int NoRoom { get; set; }
public int NoToilet { get; set; }
public string PropertyType { get; set; }
public string PropertyStatus { get; set; }
public double SalePrice { get; set; }
public double RentPricePerMonth { get; set; }
public bool IsAvailable { get; set; }
...............
And Here is my User Class :
public class User
{
public int UserId { get; set; }
public string UserName { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public string Password { get; set; }
public string PhoneNo { get; set; }
public string Email { get; set; }
Now I want to create report using Property class and also want to show User class.
I am able to show objects of Property class but not able to show User Class.
How can I do this?
Currently I am generating report using this :
Property p = Property.GetPropertyByPropertyId(propertyId);
PropertyBindingSource.DataSource = p;
reportViewer1.RefreshReport();
1.implement the Serializable interface to "User" class
[Serializable]
public class User
{
2.If, in case you want to display the user name,
In the design of the report, the expression of the item set a
=Fields!Owner.Value.UserName

EF 4: System.Data.Entity.Edm.EdmEntityType: Name: Each type name in a schema must be unique

I want to use EF code first approach.
I have read this post:
http://weblogs.asp.net/scottgu/archive/2010/07/16/code-first-development-with-entity-framework-4.aspx
and created my BL classes
public class AppData
{
public string Id { get; set; }
public string Url { get; set; }
public AppData_OptionsDialog OptionsDialog { get; set; }
public AppData_Compatibility Compatibility { get; set; }
}
public class AppData_Compatibility
{
public int Id { get; set; }
public string Platform { get; set; }
public string MaxVersion { get; set; }
}
public class AppData_OptionsDialog
{
public int Id { get; set; }
public string DisplayName { get; set; }
public string AppDesc { get; set; }
public string PrivacyPolicyUrl { get; set; }
public string TermsOfUseUrl { get; set; }
}
public class AppsDataContext : System.Data.Entity.DbContext
{
public AppsDataContext() : base("MaMDB") { }
public DbSet<Conduit.Mam.Common.BlData.AppsData.AppData> AppsData { get; set; }
public DbSet<Conduit.Mam.Common.BlData.AppsData.AppData_Compatibility> AppData_Compatibilities { get; set; }
public DbSet<Conduit.Mam.Common.BlData.AppsData.AppData_OptionsDialog> AppData_OptionsDialogs { get; set; }
}
I have created corrisponding tables in the DB.
I understand EF uses convention over configuration.
So is it magically maps the classes to the DB? no need to generate an em
I try to execute a test on of the methods:
public IList<Conduit.Mam.Common.BlData.AppsData.AppData> GetAll()
{
var apps = from app in AppsDataContext.AppsData
select app;
return apps.ToList();
}
but get the following error:
One or more validation errors were detected during model generation:
\tSystem.Data.Entity.Edm.EdmEntityType: Name: Each type name in a
schema must be unique. Type name 'AppData_OptionsDialog' is already
defined. \tSystem.Data.Entity.Edm.EdmEntityType: Name: Each type name
in a schema must be unique. Type name 'AppData_Compatibility' is
already defined.
I have seen this answer, but it didn't help me
Entity Framework error - "The EntityContainer name must be unique"
I think I know what the problem is, even though this is incredibly old, I'm running across the same problem now, it seems EF doesn't like it when you have:
public class User_Roles {
public bool Admin { get; set; }
public bool Moderator { get; set; }
public virtual User User { get; set; }
}
public class User {
public Guid Id { get; set; }
public string Username { get; set; }
public string Salt { get; set; }
public string Password { get; set; }
public virtual User_Roles Roles { get; set; }
}
In this case, either User_Roles needs to be renamed or the Roles property in User needs to be renamed, as so:
public class URoles {
public bool Admin { get; set; }
public bool Moderator { get; set; }
public virtual User User { get; set; }
}
public class User {
public Guid Id { get; set; }
public string Username { get; set; }
public string Salt { get; set; }
public string Password { get; set; }
public virtual URoles Roles { get; set; }
}
or you could simply change the "Roles" property in User:
public class User_Roles {
public bool Admin { get; set; }
public bool Moderator { get; set; }
public virtual User User { get; set; }
}
public class User {
public Guid Id { get; set; }
public string Username { get; set; }
public string Salt { get; set; }
public string Password { get; set; }
public virtual User_Roles URoles { get; set; }
}
in your case, this is happening on:
public AppData_OptionsDialog OptionsDialog { get; set; }
public AppData_Compatibility Compatibility { get; set; }
Either rename the class, or rename the properties.

Categories

Resources