Difficulty using "public virtual" variables in database creation - asp.net-mvc-3

I am creating two tables in Visual Web Developer 2010 Express using the following code:
http://imgur.com/a/Mi2Bv (sorry, the forum will not let me, due to a new account, post pictures directly)
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
namespace BarApp.Models
{
public class Drinks
{
public int DrinksId { get; set; }
public int EstablishmentsID { get; set; }
public string name { get; set; }
public decimal price { get; set; }
public string description { get; set; }
public string image { get; set; }
public virtual Establishments establishment { get; set; }
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
namespace BarApp.Models
{
public class Promotions
{
public int PromotionsId { get; set; }
public string name { get; set; }
public float discount { get; set; }
public int EstablishmentId { get; set; }
public int DrinkId { get; set; }
public string description { get; set; }
public virtual Establishments establishment { get; set; }
public virtual Drinks drink { get; set; }
}
}
But when I look at the created tables, the Promotions table has actual rows for the public virtual code, whereas the Drinks table does not.
I am able to have the Drinks table function the way I want elsewhere in the project, but I cannot get Promotions to behave the same way because it appears that "public virtual" is giving different results in each table.
I do not understand why my Promotions table is actually creating rows for the public virtual variables. Can someone help me understand?

In this particular situation I was not using the conventional way of referencing the Id field of another table.
I simply needed to change the following:
public int EstablishmentId { get; set; }
public int DrinkId { get; set; }
to the following:
public int EstablishmentsId { get; set; }
public int DrinksId { get; set; }
My tables were created as expected after I made this change.

Related

How to handle char property properly in Hotchocolate Graphql 12.0?

I am trying to implement filtering on Resource table which has MartialStatus of char property in DDL of database.Let my show you my approach first. In my program.cs file, i have the following:
using LIS.ResourcePlanningSystem.API;
using LIS.ResourcePlanningSystem.Data;
using Microsoft.EntityFrameworkCore;
var builder = WebApplication.CreateBuilder(args);
// Add services to the container.
builder.Services.AddControllers();
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
builder.Services.AddDbContext<RpsDbContext>(options => options.UseLazyLoadingProxies().UseNpgsql(builder.Configuration.GetConnectionString("RPSDbContext")));
builder.Services.AddGraphQLServer().
RegisterDbContext<RpsDbContext>().
AddQueryType<Query>().
AddProjections().
AddFiltering().
AddSorting().
BindRuntimeType<char, StringType>().
AddTypeConverter<char, string>(from => from.ToString()).
AddTypeConverter<string, char>(from => from.ToCharArray()[0]);
var app = builder.Build();
// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
app.UseSwagger();
app.UseSwaggerUI();
}
app.UseHttpsRedirection();
app.UseAuthorization();
app.MapControllers();
app.MapGraphQL("/graphql");
app.Run();
Here is my a model Register.cs which has "MaritalStatus" char property.
public class Resource
{
public int Id { get; set; }
public string? FirstName { get; set; }
public string? MiddleName { get; set; }
public string? LastName { get; set; }
public string? FullName { get; set; }
public char? MaritalStatus { get; set; }
public virtual Gender? Gender { get; set; }
public virtual Education? Education { get; set; }
public int? InstitutionId { get; set; }
public string? PerStreet { get; set; }
public DateTime? OfficeJoinDt { get; set; }
public virtual Grade? Grade { get; set; }
public int? PositionId { get; set; }
public virtual Department? Department { get; set; }
public virtual ClientType? ClientType{ get; set; }
public int? ExpOut { get; set; }
public string? ResignedFlag { get; set; }
public string? Email { get; set; }
public virtual BloodGroup? BloodGroup { get; set; }
public virtual ResignedRemarks? ResignedRemark { get; set; }
public virtual Source? Source { get; set; }
}
Now, the program runs just fine until i add [UseFiltering] on the Resource table in query.cs file.
[UseFiltering]
[UseSorting]
public IQueryable<Resource>? GetResources(RpsDbContext context) => context.Resources;
The error i am getting is this:
HotChocolate.SchemaException: For more details look at the `Errors` property.
1. For more details look at the `Errors` property.
1. The type of the member MaritalStatus of the declaring type Resource is unknown
If i remove the [UseFiltering] [UseSorting], the program works fine. I think the problem is related to filtering on resource table. Filtering also work fine on all the other tables which doesn't have char property in its schema definition. Someone has opened a bug issue on github [here] . Tried to solve reading this issue but no luck. Could somebody please tell me how can i get around this problem?

Foreign Keys or virtual fields

I have a Project table with some fields that point to a Participant table but all with a different meaning of course:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
namespace iMaSys.Models
{
public class Project
{
[Key]
public int ProjectID { get; set; }
[Required]
[StringLength(128)]
[Display(Name = "Omschrijving")]
public string Description { get; set; }
[DataType(DataType.Date)]
[DisplayFormat(DataFormatString = "{0:yyyy-MM-dd}", ApplyFormatInEditMode = true)]
[Display(Name = "Startdatum")]
public DateTime StartDate { get; set; }
[DataType(DataType.Date)]
[DisplayFormat(DataFormatString = "{0:yyyy-MM-dd}", ApplyFormatInEditMode = true)]
[Display(Name = "Einddatum")]
public DateTime? EndDate { get; set; }
public Boolean Active { get; set; }
[Display(Name = "Mediation Casenummer")]
public string Mediation_casenr { get; set; }
public Participant CaseManager { get; set; }
public Participant Supervisor { get; set; }
public Participant Party_1 { get; set; }
public Participant Party_2 { get; set; }
public Participant Client { get; set; }
public Participant InterventionManager { get; set; }
public Participant Mediator { get; set; }
public virtual ProjectCategorySub ProjectCategorySubject { get; set; }
}
}
The fields Casemanager, Supervisor, Party_1 etc all point to Participant. In Particpant I added InverseProperties to tell the framework the connection between Projects and Participants:
[InverseProperty("Mediator")]
public List<Project> ProjectMediators { get; set; }
[InverseProperty("Supervisor")]
public List<Project> ProjectSupervisors { get; set; }
etc. etc.
After add-migration and update-database the fields in Project are named like:
CaseManager_ParticipantID etc. I just simply need CaseManagerID to point to Participant_ParticipantID. I tried several things but I seem not to understand howto get it to work.
I'm stuck on this one, can anyone point me in the right direction?
Best regards, Janno Hordijk
I solved it myself but want to share what I found out.
At Participant:
[InverseProperty("Mediator")]
public virtual ICollection<Project> MediatorProjects { get; set; }
[InverseProperty("Supervisor")]
public virtual ICollection<Project> SupervisorProjects { get; set; }
At Project:
[ForeignKey("Mediator")]
public int? Mediator_ID { get; set; }
public virtual Participant Mediator { get; set; }
[ForeignKey("Supervisor")]
public int? Supervisor_ID { get; set; }
public virtual Participant Supervisor { get; set; }
Now the database is ok and my fieldnames are Supervisor_ID instead of Supervisor_Participant_ID
Best regards, Janno

Why can't I use the Column data annotation with Entity Framework 5?

I want to use the Column data annotation as shown in the sample code below but the compiler (and also IntelliSense) do not seem to know that particular data annotation. I'm using EF 5 in Visual Studio 2010. I installed EF 5 using NuGet. The Required and MaxLength annotations are working.
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
namespace Model
{
public class Destination
{
public int DestinationId { get; set; }
[Required]
public string Name { get; set; }
public string Country { get; set; }
[MaxLength(500)]
public string Description { get; set; }
[Column(TypeName="image")]
public byte[] Photo { get; set; }
public List<Lodging> Lodgings { get; set; }
}
}
What am I missing?
Column is in:
using System.ComponentModel.DataAnnotations.Schema;
the following code:
using System.ComponentModel.DataAnnotations.Schema;
using System.Data.Entity;
namespace ConsoleApplication2
{
public class MyContext : DbContext
{
public IDbSet<Entity> Entities { get; set; }
}
public class Entity
{
public int Id { get; set; }
[Column(TypeName = "image")]
public byte[] Photo { get; set; }
}
}
produces:

Setting table level WillCascadeOnDelete not available

I'm pulling out my hair here. I've seen the solutions to turning off cascade on delete here, but I can't implement it. I don't know what I'm doing wrong here, but I keep getting the below error:
'System.Data.Entity.ModelConfiguration.EntityTypeConfiguration' does not contain a definition for 'WillCascadeOnDelete' and no extension method 'WillCascadeOnDelete' accepting a first argument of type 'System.Data.Entity.ModelConfiguration.EntityTypeConfiguration' could be found (are you missing a using directive or an assembly reference?)
I've added the necessary namespaces, but I don't see it as an option anywhere in the intellisense and I'm not getting anywhere searching. I'm in VS 2010 MVC 3
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using vf2.Models;
using vf2.Models.LinkTables;
using vf2.Models.Requests;
using System.Data.Entity;
using System.Data.Entity.ModelConfiguration.Conventions;
using System.Data.Entity.ModelConfiguration.Configuration;
using System.Data.Entity.ModelConfiguration;
using vf2.Models.Reporting;
using vf2.Models.POSObj;
namespace vf2.Models
{
public class vfContext : DbContext
{
public DbSet<App> Apps { get; set; }
public DbSet<Origin> Origins { get; set; }
public DbSet<WineType> WineTypes { get; set; }
public DbSet<VarType> VarTypes { get; set; }
public DbSet<Wine> Wines { get; set; }
public DbSet<Vintage> Vintages { get; set; }
public DbSet<Distributor> Distributors { get; set; }
public DbSet<Importer> Importers { get; set; }
public DbSet<Producer> Producers { get; set; }
public DbSet<Publication> Publications { get; set; }
public DbSet<Review> Reviews { get; set; }
public DbSet<UserType> UserTypes { get; set; }
public DbSet<Restaurant> Restaurants { get; set; }
public DbSet<WineListChangeRate> WineListChangeRates { get; set; }
public DbSet<MenuChangeRate> MenuChangeRates { get; set; }
public DbSet<WineListCount> WineListCounts { get; set; }
public DbSet<UserObj> UserObjs { get; set; }
public DbSet<ProducerUser> ProducerUsers { get; set; }
public DbSet<DistributorUser> DistributorUsers { get; set; }
public DbSet<RestaurantUser> RestaurantUsers { get; set; }
public DbSet<ProducerEditRequest> ProducerEditRequests { get; set; }
public DbSet<RequestStatus> RequestStatuses { get; set; }
public DbSet<VOAVIRequest> VOAVIRequests { get; set; }
public DbSet<POS> POSs { get; set; }
public DbSet<Cart> Carts { get; set; }
public DbSet<FutureUser> FutureUsers { get; set; }
public DbSet<Doc> Docs { get; set; }
public DbSet<DocType> DocTypes { get; set; }
public DbSet<WineVisit> WineVisits { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<Review>().WillCascadeOnDelete(false);
//error here!
base.OnModelCreating(modelBuilder);
}
}
}
"Cascading delete" is a configuration of a relationship, not of an entity/table. Hence WillCascadeOnDelete is a method of CascadableNavigationPropertyConfiguration. Use case example:
modelBuilder.Entity<Review>()
.HasRequired(r => r.Wine)
.WithMany()
.WillCascadeOnDelete(false);
It means that if a wine is deleted from the catalog in the database, it's reviews should not be deleted together with the wine. That's a property of this specific relationship, not of the Reviews table.
In this case trying to delete a wine which has reviews would result in a foreign key constraint violation and exception of course, but that is what you usually want when you disable cascading delete on a required relationship ("Don't allow to delete a wine which has reviews, only allow it for wines which haven't any...").

How to make the entity key value user-assigned

I'm retrieving data from another database that has already created unique IDs for each "beer" entity. However, when I assign the unique key value from the remote database to a new "beer" object, it gets replaced as soon as the object is inserted into the database.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.ComponentModel.DataAnnotations;
using BeerRecommender.Models.ViewModels;
namespace BeerRecommender.Models
{
public class Beer
{
public Beer()
{
Created = DateTime.Now;
Updated = DateTime.Now;
}
[Key]
public int ID { get; set; }
public string Name { get; set; }
public string Description { get; set; }
public Brewery Brewery { get; set; }
public DateTime Created { get; set; }
public DateTime Updated { get; set; }
public ICollection<City> Cities { get; set; }
public ICollection<Tag> Tags { get; set; }
public Style Style { get; set; }
}
}
I'm using the UnitOfWork pattern.
UnitOfWork.BeerRepository.Insert(beer);
UnitOfWork.Save();
As you already discovered, EF will generate values for int primary keys. To fine tune this behavior you need to mark your key with the DatabaseGenerated attribute (or you can also configure this with the the fluent api's HasDatabaseGeneratedOption method):
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.None)]
public int ID { get; set; }

Resources