I'm working with code that was started by someone other than me, so I'm not entirely familiar with the structure. However, I decided I needed to change one of the variables in one of the models. I needed to switch it from
[ForeignKey("JobFunctionDemandId")]
public virtual JobFunctionDemand JobFunctionDemand { get; set; }
public int JobFunctionDemandId { get; set; }
to
[ForeignKey("SpecificRequirementId")]
public virtual SpecificRequirement SpecificRequirement { get; set; }
public int SpecificRequirementId { get; set; }
I thought this would be a relatively small change. I realized, however, that these variables correspond to tables in a database, and so I switched all instances of JobFunctionDemand and JobFunctionDemandId to SpecificRequirement and SpecificRequirementId respectively. However, now when I try to run the Update-Database command in the package manager console, I get the error "The project 'ProjectName' failed to build."
I'm guessing the issue here is that I'm modifying the structure of an existing database, but I'm not really sure how to fix it.
Related
I am having the weirdest problem right now ...
I am working on a program that tries to instantiate types (DbContext derivatives) from another project. Because the DbContexts don't simply accept standard parameters but only interfaces from that other projects I had to take some of the other project's assemblies and reference them so I could create dummy-types that implement the interfaces.
The main one is this:
class ContextConfigurationDummy:IContextConfiguration
{
#region privates
private ILogger GetLoggerDummy() => new LoggerDummy();
private ITenantSchemaResolver GetSchemaResolverDummy() => new SchemaResolverDummy();
private CultureInfo GetUserCulture() => new CultureInfo("en-US");
private DatabaseMetadata GetDbMetadata() => new DatabaseMetadata();
private IEntityValidatorFactory GetValidatorFactory() => new ValidatorFactoryDummy();
#endregion
public DbConnection GetDbConnection() => new SqlConnection(#"[insert connection string]");
public RuminantDummy GetRuminant() => new RuminantDummy();
public Func<CultureInfo> UserCulture { get; set; }
public Func<DbConnection> Connection { get; set; }
public Func<IDatabaseMappingRuminant> Ruminant { get; set; }
public Func<DatabaseMetadata> DatabaseMetadata { get; set; }
public IEntityValidatorFactory ValidatorFactory { get; set; }
public Func<ITenantSchemaResolver> TenantSchemaResolver { get; set; }
public Func<ILogger> Logger { get; set; }
public ContextConfigurationDummy()
{
UserCulture = GetUserCulture;
Connection = GetDbConnection;
Ruminant = GetRuminant;
DatabaseMetadata = GetDbMetadata;
ValidatorFactory = GetValidatorFactory();
TenantSchemaResolver = GetSchemaResolverDummy;
Logger = GetLoggerDummy;
}
}
The original interface is this:
public interface IContextConfiguration
{
Func<CultureInfo> UserCulture { get; set; }
Func<DbConnection> Connection { get; set; }
Func<IDatabaseMappingRuminant> Ruminant { get; set; }
Func<DatabaseMetadata> DatabaseMetadata { get; set; }
IEntityValidatorFactory ValidatorFactory { get; set; }
Func<ITenantSchemaResolver> TenantSchemaResolver { get; set; }
Func<ILogger> Logger { get; set; }
}
Everything was working just fine, I didn't look at that part of the code for a while, did quite a few changes to the rest (including to the project itself to adapt it for continuous integration), when I was done I started testing again and, when calling the constructor of ContextConfigurationDummy, I was faced with this:
Note how the debugger has not even tried to evaluate it yet! A "normal" error would be that the value is null and after it tries to evaluate it there would be some kind of exception. Not here. There isn't even any file being loaded in this class. Same error for all the following fields
I figured I had to have broken something while working on the project structure, so I remade the entire project, took only the code, re-referenced the assemblies, left everything at default ... and had the exact same error again. So, it has to be the code right?
Well, I reverted to an old commit through git, ran the program, everything working as it should. Great. Checked the code - the relevant parts are exactly the same, except for the Namespaces which were slightly adapted. So, not the code either?
I went back to my current commit and after trying different kinds of ways to reference the external assemblies I tried something else once again: Just for lulz I went into my Main, the Start of the program and tried to instantiate the class with exactly the same line I used to originally instantiate it: var dummy = new ContextConfigurationDummy();
It works. Everything as expected, my class just instantiates normally.
But as if this wasn't weird enough, I'll do you one better:
After calling the method in the main I kept the program running. I got back to the spot where I originally called new ContextConfigurationDummy(). Back into the constructor and ... it works there as well. Took the line out the main - doesn't work. Back in - works again.
I'm beyond stumped, please help. (and don't tell me to clean my solution, I've done so a hundred times and literally remade the entire thing) .
I'm effectively comibining answers from my own experiences and some google-fu here but.
.NET Version
Make sure you're using the same .NET version. I've had it where I've created a new project with an old .NET version and it's screwed me completely with the same issue.
Assembly Names
Make sure none of your dlls share the same name with the assembly you're bringing in. If you have two MyAssembly.dlls it could be looking for the wrong one / version. Additionally if you've updated the other project at some point, check that all your references are using the same version of a brought in dll.
Nuget Packages
Have you updated any Nuget packages in your project that are required by the other assembly also? (I've had this many times with my unit tests) if so you'll either need to update the other projects nuget packages to the same verison, or possibly add an App.Config file to tell it to use the newer version.
I've never had the same assembly names issue, but I've had the nuget package issue and the .net version issue quite a few times (It's something you just don't think about)
i'm writing a system to track observation values from sensors (e.g. temperature, wind direction and speed) at different sites. I'm writing it in C# (within VS2015) using a code-first approach. Although i've a reasonable amount of programming experience, I'm relatively new to C# and the code-first approach.
I've defined my classes as below. I've built a REST api to accept observation reading through Post, which has driven my desire to have Sensor keyed by a string rather than an integer - Some sensors have their own unique identifier built in. Otherwise, i'm trying to follow the Microsoft Contoso university example (instructors - courses- enrolments).
What I am trying to achieve is a page for a specific site with a list of the sensors at the site, and their readings. Eventually this page will present the data in graphical form. But for now, i'm just after the raw data.
public class Site
{
public int Id { get; set; }
public string Name { get; set; }
public ICollection<Sensor> Sensors { get; set; }
}
public class Sensor
{
[Key]
public string SensorName { get; set; }
public int SensorTypeId { get; set; }
public int SiteId { get; set; }
public ICollection<Observation> Observations { get; set; }
}
public class Observation
{
public int Id { get; set; }
public string SensorName { get; set; }
public float ObsValue { get; set; }
public DateTime ObsDateTime { get; set; }
}
and I've created a View Model for the page I'm going to use...
public class SiteDataViewModel
{
public Site Site { get; set; }
public IEnumerable<Sensor> Sensors { get; set;}
public IEnumerable<Observation> Observations { get; set; }
}
and then i try to join up the 3 classes into that View Model in the SiteController.cs...
public actionresult Details()
var viewModel.Site = _context.Sites
.Include(i => i.Sensors.select(c => c.Observations));
i used to get an error about "cannot convert lambda expression to type string", but then I included "using System.Data.Entity;" and the error has changed to two errors... on the 'include', I get "cannot resolve method 'include(lambda expression)'...". And on the 'select' i get "Icollection does not include a definition for select..."
There's probably all sorts of nastiness going on, but if someone could explain where the errors are (and more importantly why they are errors), then I'd be extremely grateful.
Simply you can you use like
viewModel.Site = _context.Sites
.Include("Sensors).Include("Sensors.Observations");
Hope this helps.
The way your ViewModel is setup, you're going to have 3 unrelated sets of data. Sites, sensors, and observations. Sites will have no inherent relation to sensors -- you'll have to manually match them on the foreign key. Realistically, your ViewModel should just be a list of Sites. You want to do
#Model.Sites[0].Sensors[0].Observations[0]
not something convoluted like
var site = #Model.Sites[0]; var sensor = #Model.Sensors.Where(s => SiteId == site.Id).Single(); etc...
Try doing
viewModel.Site = _context.Sites.Include("Sensors.Observations").ToList();
Eager-loading multiple levels of EF Relations can be accomplished in just one line.
One of the errors you reported receiving, by the way, is because you're using 'select' instead of 'Select'
And lastly, be aware that eager-loading like this can produce a huge amount of in-memory data. Consider splitting up your calls for each relation, such that you display a list of Sensors, and clicking, say, a dropdown will call an API that retrieves a list of Sites, etc. This is a bit more streamlined, and it prevents you from getting held up because your page is loading so much information.
Update
I've created a sample application for you that you can browse and look through. Data is populated in the Startup.Configure method, and retrieved in the About.cshtml.cs file and the About.cshtml page.. This produces this page, which is what you're looking for I believe.
When I try to add Controller using build-in generator I get following error message:
Where "Brand" is a model class and "ApplicationDbContext" is my data context class.
I never encoutered error like this before. It does not occur all the time (2 success vs 30-40 attempts without changing single line of code). I was able to create Controller for same class minutes ago, but it's really annoying when you try to add something new and try more than 10 times with no results.
Of course, I could write my own controller and views, but I really like using included tools.
I have already repaired VS using "Modify" option in "Add or remove". I'm using latest Microsoft Visual Studio Community (MVSC2015 V14.0.25425.01 Update3).
EDIT:
Brand.cs:
namespace AppBrander.Models
{
public class Brand
{
public int ID { get; set; }
public string Email { get; set; }
public string BrandName { get; set; }
public string CompanyName { get; set; }
public string Description { get; set; }
}
}
Works in brand new project, fails in old - I guess it's just my VS installation being totally messed up. I should have been guessed, but I just did second repair...
I am trying to refactor a solution to bring on board another project.
I have a Core project where common classes across projects reside.
I've tried to simpify my question by using 2 imaginary projects: Holidays and Weather...
I have a file load process setup for the Holidays project which has the following 2 classes:
public class Job
{
public virtual string CreatedBy { get; set; }
public virtual DateTime? CreatedDate { get; set; }
public virtual Security Security { get; set; }
protected IList<File> _files = new List<File>();
public virtual IEnumerable<File> Files
{
get { return _files; }
}
}
public class File
{
public virtual string FileName { get; set; }
public virtual FileType FileType { get; set; }
public virtual FileStatusType FileStatusType { get; set; }
public virtual Job Job { get; set; }
}
The file load process for the Weather project has exactly the same structure as Holidays, except that the Jobs class does not have a Security property.
My question is, is it possible to somehow move both classes into the Core project to allow both projects to use them?
Obviously Weather does not need the Security property, so I was thinking I would have a Core.Job class without Security, and then extend the Core.Job in Holidays.Job.
But once I do that, in the Core.File class, what Job is it referring to? As it sits in the Core project it must be the Core.Job.
So would I then need to have Job and File sit in Holidays, and Weather (and any other future projects) use the Core.Job and Core.File?
I don't want the Core project to have any references to sub projects.
I am using NHibernate, and so have mapping files - adding to the complexity.
Hope this is clear enough
Thanks
You can certainly do this, but I am not sure whether it brings you true benefit:
Does the Core itself work with the base Job in any way? If it does not, implementing Job separately in each project may help you keep coupling loose, even though I'd a little redundant. In code I wrote, I have sometimes introduced unnecessary dependencies by extracting interfaces without adding true benefit. This is why I am a bit precautious.
In case Core does acutal work with it, the part to refactor into the common base Job is perhaps the interface it works with.
You may think of an interface instead of a base class. Security may semantically belong to another interface. Moreover, you hand over a lot of control over your classes to the Core.
Do you ever hand a job from one project to another (or are they mapped to the same DB table via NHibernate?)? If you don't, an internal redundant class may be fine too.
Not very clear why confuse on the soluton offered by you (assuming that I right understood you)
//Core DLL
public class Job
{
public virtual string CreatedBy { get; set; }
public virtual DateTime? CreatedDate { get; set; }
protected IList<File> _files = new List<File>();
public virtual IEnumerable<File> Files
{
get { return _files; }
}
}
in the Hollidays you have
public class HollidayJob : Job
{
public virtual Security Security { get; set; }
}
in Weather simply use a type Job, if it selfsufficient.
In this case you refer CoreDLL from Holliday project and Weather. When you serialize it via NHibernate it for HollidayJob save one field more, but when Weather reads the same table it skips that field, as don't know anything, and don't actually care abotu it.
Hope this helps.
This is the 3rd major edit to this question, so I'm going to write a quick little summary first, then ask the question.
I have an input/edit model I'm planning on using with an EF4-backed MVC 2 site. The model is as follows:
public class AdminGameEditModel
{
[Required]
public int GameID { get; set; }
[Required(ErrorMessage="A game must have a title")]
public string GameTitle { get; set; }
[Required(ErrorMessage="A short URL must be supplied")]
public string ShortURL { get; set; }
[Required(ErrorMessage="A box art image must be supplied")]
public HttpPostedFileBase BoxArt { get; set; }
[Required(ErrorMessage="A large image for the index page is required")]
public HttpPostedFileBase IndexImage { get; set; }
[Required(ErrorMessage="A game must have a review")]
public string ReviewText { get; set; }
[Required(ErrorMessage="A game must have a score")]
public int ReviewScore { get; set; }
[Required(ErrorMessage="A game must have at least one Pro listed")]
public string[] Pros { get; set; }
[Required(ErrorMessage="A game must have at least one Con listed")]
public string[] Cons { get; set; }
[Required(ErrorMessage="A game must belong to a genre")]
public int GenreID { get; set; }
[Required(ErrorMessage="A game must be associated with at least one platform")]
public int[] PlatformIDs { get; set; }
}
I'd like to map it to a Game entity for creation/updating. There's a snag, though - I need to save the images in a particular folder, and then take their paths and save those as properties in my entity. So, an example for clarity's sake: rather than my Game entity having a actual BoxArt image, it would instead have the path to the correct BoxArt image. I hope this makes sense. Let me know if I need to clarify.
Can I do this with AutoMapper? If so, can anyone provide some code guidance?
EDIT:
Part of the problem is that my model is fairly complex, as it contains a many-to-many relationship. The PlatformIDs are ultimately used to build/rebuild (depending whether I'm creating or updating an entity) linked Platform entities in the Game/Platform map. I'm not sure if AutoMapper can do something that complex without needing to go through my repository.
Then there's the problem of the image paths. The paths aren't a property of HttpPostedFileBase, but must be constructed by hand like so:
if (BoxArt.ContentLength > 0) {
var fileName = Path.GetFileName(BoxArt.FileName);
var path = Path.Combine(Server.MapPath("~/Content/Images/BoxArt"), fileName);
BoxArt.SaveAs(path);
}
So, what I'm looking for is more complex than just trying to map simple properties across objects. I'd like to keep a reference to my edit model out of my repository. Separation of concerns, and all that. Because of that, I need to map to an entity before I attempt to pass it to my repo for saving. I'm just not sure how to do it without blending app layers.
If I understand you, all you need to do is update your properties first prior to the call to AutoMapper.
Make sure your object has the correct values prior to calling AutoMapper.
After the call to do the mapping, your destination object will have all the matching properties copied over.
Post some more code if this doesn't answer the questoin.