Cast IEnumerable<Inherited> To IEnumerable<Base> - c#

I'm trying to cast an IEnumerable of an inherited type to IEnumerable of base class.
Have tried following:
var test = resultFromDb.Cast<BookedResource>();
return test.ToList();
But getting error:
You cannot convert these types. Linq to Entities only supports conversion primitive EDM-types.
The classes involved look like this:
public partial class HistoryBookedResource : BookedResource
{
}
public partial class HistoryBookedResource
{
public int ResourceId { get; set; }
public string DateFrom { get; set; }
public string TimeFrom { get; set; }
public string TimeTo { get; set; }
}
public partial class BookedResource
{
public int ResourceId { get; set; }
public string DateFrom { get; set; }
public string TimeFrom { get; set; }
public string TimeTo { get; set; }
}
[MetadataType(typeof(BookedResourceMetaData))]
public partial class BookedResource
{
}
public class BookedResourceMetaData
{
[Required(ErrorMessage = "Resource id is Required")]
[Range(0, int.MaxValue, ErrorMessage = "Resource id is must be an number")]
public object ResourceId { get; set; }
[Required(ErrorMessage = "Date is Required")]
public object DateFrom { get; set; }
[Required(ErrorMessage = "Time From is Required")]
public object TimeFrom { get; set; }
[Required(ErrorMessage = "Time to is Required")]
public object TimeTo { get; set; }
}
The problem I'm trying to solve is to get records from table HistoryBookedResource and have the result in an IEnumerable<BookedResource> using Entity Framework and LINQ.
UPDATE:
When using the following the cast seams to work but when trying to loop with a foreach the data is lost.
resultFromDb.ToList() as IEnumerable<BookedResource>;
UPDATE 2:
Im using entity frameworks generated model, model (edmx) is created from database, edmx include classes that reprecent the database tables.
In database i have a history table for old BookedResource and it can happen that the user want to look at these and to get the old data from the database entity framework uses classes with the same name as the tables to receive data from db. So i receive the data from table HistoryBookedResource in HistoryBookedResource class.
Because entity framework generate the partial classes with the properties i dont know if i can make them virtual and override.
Any suggestions will be greatly appreciated.

Typically you use AsEnumerable<T> in such cases:
var test = resultFromDb.AsEnumerable().Cast<BookedResource>();
This has the advantage of not enumerating the whole result at once (you don't loose the laziness).

try with:
resultFromDb.AsEnumerable().Cast<BookedResource>();

Related

EF Core name mapping

I've been trying to figure out how to do the following (although my research did not help): I have the these three classes:
public abstract class Classifier
{
public int ClassifierId { get; set; }
public string ClassifierName { get; set; }
public DateTime DateAdded { get; set; }
}
public class ManualClassifier : Classifier
{
public int ManualClassifierId { get; set; }
public string user_name { get; set; }
public string userName { get; set; }
public string firstName { get; set; }
public string lastName { get; set; }
public string email { get; set; }
public string password { get; set; }
}
public class ToolClassifier : Classifier
{
public int ToolId { get; set; }
public string ToolName { get; set; }
}
Both the ManualClassifier and ToolClassifer inherit from Classifier. I'm using EF Core to map this to a database but the question is the following: I've already searched a bit and I must make use of a descriminator which basically is an implicitly created column that will say the type of, in this case, classifier. So far so good. The issue arises when I have a property called ManualClassifierId as well as a ToolId. I want this two properties to map to the ClassifierId property. So in the table representing the entity Classifier, the ClassifierId property will either be the ManualClassifierId or the ToolId.
How can I achieve this mapping? Also, this solution would mean that both child classes would both have empty fileds in the tables (due to inheriting the three properties from the Classifier class). Is there a better solution? Perhaps just erase the Id's from both child classes a let them inherit the parent one?
Thank you in advance!
To use the same column name in both classes, you can add a Column attribute to both properties. Then they will both use that column name in the database. See ColumnAttribute(String).
Use it like this:
public class ManualClassifier : Classifier
{
[Column(Name="ClassifierId")]
public int ManualClassifierId { get; set; }
...........
}
Do the same with ToolId.

Is there a way to control the order of properties in JSON objects?

I'm using Entity Framework Core, and the generated class has its own properties, i.e.
DataModel.Agent.cs
public partial class Agent {
public virtual decimal Id
{
get;
set;
}
public virtual string Name
{
get;
set;
}
}
But I need other properties, so I declare them in another file:
Agent.cs
public partial class Agent
{
[NotMapped]
public dynamic Custom { get; set; }
}
The problem is that Agent.cs is compiled before DataModel.Agent.cs, so the compiler generates properties in this order: Custom, Id, Name, and the resulting JSON is weird.
I want it to be: Id, Name, Custom. In other words, I always want the DataModel class to come first.
EDIT: Just to clarify, the only objective is to make the JSON prettier by always putting the Id first, which is a very common pattern. This has absolutely no impact on how the application works.
Is there a way to force the compiler to always compile one of the files first?
Well you really shouldn't count on JSON property order BUT if using json.net
public class Account
{
public string EmailAddress { get; set; }
// appear last
[JsonProperty(Order = 1)]
public bool Deleted { get; set; }
[JsonProperty(Order = 2)]
public DateTime DeletedDate { get; set; }
public DateTime CreatedDate { get; set; }
public DateTime UpdatedDate { get; set; }
// appear first
[JsonProperty(Order = -2)]
public string FullName { get; set; }
}
http://www.newtonsoft.com/json/help/html/JsonPropertyOrder.htm

The entity type 'Microsoft.AspNet.Mvc.Rendering.SelectListGroup' requires a key to be defined

Not sure what happened but I am getting the following error while attempting to pull up any view in my web app. The code is auto generated by visual studio and I am not getting any errors before building. Using ASP.Net MVC 6, EF7.
An exception of type 'System.InvalidOperationException' occurred in EntityFramework.Core.dll but was not handled in user code
Additional information: The entity type 'Microsoft.AspNet.Mvc.Rendering.SelectListGroup' requires a key to be defined.
Here is the line the code is erroring out on.
public IActionResult Index()
{
var schoolContext = _context.Schools
.Include(s => s.District)
.Include(s => s.Location)
.Include(s => s.Tier);
return View(schoolContext.ToList());
}
After some searching I can't figure out exactly what I need to fix. This was working at one point. Not sure what changed.
The view does have a defenition
#model IEnumerable<School>
As requested here is the School model
public class School
{
//Original Fields
public int SchoolId { get; set; }
[Display(Name = "Name")]
public string SchoolName { get; set; }
[Display(Name = "Date Added")]
public DateTime SchoolDateAdded { get; set; }
[Display(Name = "Last Update")]
public DateTime SchoolLastUpdate { get; set; }
[Display(Name="Updated By")]
public string SchoolUpdatedBy { get; set; }
//Referance Fields
public int DistrictId { get; set; }
public IEnumerable<SelectListItem> DistrictList { get; set; }
public int LocationId { get; set; }
public IEnumerable<SelectListItem> LocationList { get; set; }
public int TierId { get; set; }
public IEnumerable<SelectListItem> TierList { get; set; }
//Navigation Property
public District District { get; set; }
public Location Location { get; set; }
public Tier Tier { get; set; }
}
These IEnumerable<SelectListItem>s should not be part of your EF model. Remember the single responsibility principle. Keep any UI framework away from your DAL implementation. Use a view model representing a School.
As for the error, from EF's point of view, School has a 1-n association with SelectListItem, so it tries to make it part of its mapping schema. But each mapped type needs a primary key, which of course isn't mapped, and EF can't infer any.
A quick, but dirty, fix would be to exclude the properties from being mapped by the [NotMapped] attribute, but a better segregation of your code is the real remedy.

Limit fields of embedded documents

I'm using the official MongoDB C# Driver to communicate with my MongoDB Servers.
This is my complete entity scheme:
public class Person
{
public ObjectId _id { get; set; }
public String FirstName { get; set; }
public String LastName { get; set; }
public DateTime DateOfBirth { get; set; }
public List<Address> Addresses { get; set; }
}
public class Address
{
public String Street { get; set; }
public String City { get; set; }
}
Now, in several cases i just want to get the following return:
public class Person_LocationOview
{
public String LastName { get; set; }
public List<Address_CityOnly> Addresses { get; set; }
}
public class Address_CityOnly
{
public String City { get; set; }
}
The default behavior to load all fields and do the mapping by myself
MongoCursor<Person>
is senseless, because I just want to load the specific fields.
With the help of reflection I generate the fields to load and send:
var fields = new { "LastName", "Addresses.City" };
MongoCollection< BsonDocument >.FindAllAs< Person_LocationOview >( )
.SetFields( fields ).ToList( );
I thought the serializer of MongoDB would be intelligent; but the call returns following error:
System.IO.FileFormatException: Required element 'City' for property 'City' of class Models.Address_CityOnly is missing
Any ideas to this requirement?
I've updated the complete MongoDB infrastructure. Now the code works with all viewModels such as Person_LocationOview. With the full scheme classes, the code still crashes and I do not know why.
Now, all my view classes are implementing an own interface (IPartialEntityView).
In my reflection method to get the field names I'll check this inheritance and only then I will load "Addresses.FieldName(s)". If the property type is no default .NET type or does not inherit IPartialEntityView I will use the complete field "Adresses".
That works great.
Thanks for all.

Foreign Key Relationship EF Code First

I'm busy creating my first EF code first model and I've come across a slightly confusing problem.
I have a number of model classes that each inherit from a base model class that has three common properties I want used in all model classes. These properties are Id, LastUpdated and LastUpdatedBy.
Id is the primary key of each model class.
LastUpdated is a foreign key to my 'User' model class.
LastUpdatedBy is a datetime field that indicates the last time the record was modified.
So what I'd like to setup is the 1 to 1 foreign key relationship from my base class to my 'User' model class but I'm receiving the exception:
Multiplicity is not valid in Role 'Profile_LastUpdatedByUser_Source'
in relationship 'Profile_LastUpdatedByUser'. Because the Dependent
Role properties are not the key properties, the upper bound of the
multiplicity of the Dependent Role must be '*'
This is my ModelBase class:
public class ModelBase
{
public int Id { get; set; }
public DateTime LastUpdated { get; set; }
[ForeignKey("LastUpdatedByUser")]
[Required]
public int LastUpdatedByUserId { get; set; }
public virtual User LastUpdatedByUser { get; set; }
}
This is one of my model classes:
public class Profile : ModelBase
{
[StringLength(25, MinimumLength=1)]
[Required(ErrorMessage="First Name is Required")]
public string FirstName { get; set; }
[StringLength(25, MinimumLength = 1)]
[Required(ErrorMessage = "Last Name is Required")]
public string LastName { get; set; }
[StringLength(25, MinimumLength = 1)]
[Required(ErrorMessage = "Email Address is Required")]
public string Email { get; set; }
public string Mobile { get; set; }
public string HomePhone { get; set; }
public string WorkPhone { get; set; }
public string ImageSource { get; set; }
public Squable.Model.Enums.MembershipType.MembershipTypeEnum MembershipType { get; set; }
}
This is my user class (Please ignore the Password property, I'll fix that later ;) ):
public class User : ModelBase
{
public string UserName { get; set; }
public string Password { get; set; }
public int ProfileId { get; set; }
public virtual Profile Profile { get; set; }
}
I don't know if what I am doing is best practise but I could do with some advice as to how to either fix the problem or maybe just some pointers in the right direction.
Move
public int Id { get; set; }
to User class and to Profile you can also change the names to UserId and to ProfileId and move
public virtual User LastUpdatedByUser { get; set; }
to Profile class.
I have a bad experience with sharing Id in base entity If you are planning to use Repository and UnitOfWork pattern you will get a lot of problems later. Check your current database structure and tables with SQL Server Management Studio.
More Info TPH

Categories

Resources