asp.net c# and mongodb models - c#

I wanna know if i can use mongodb like models (model classes) in my project (asp.net mvc 4 c#).
For example:
namespace Demo.Models
{
public class Model1
{
public int ID { get; set; }
public string Title { get; set; }
public DateTime ReleaseDate { get; set; }
public string Genre { get; set; }
public decimal Price { get; set; }
}
public class MovieDBContext : DbContext
{
public DbSet<Model1> models { get; set; }
}
}
Let's say this is standard model for mssql database. Can i create models like this to use MongoDB collections, documents?
If yes, how? (if you can provide me with link of some examples).
Thanks.

Yes you can don't forget to add BsonId attribute, because every object has to have his own unique id.
public class Model1
{
[BsonId]
public int ID { get; set; }
public string Title { get; set; }
public DateTime ReleaseDate { get; set; }
public string Genre { get; set; }
public decimal Price { get; set; }
}
And example you can find here:
http://www.joe-stevens.com/2011/10/02/a-mongodb-tutorial-using-c-and-asp-net-mvc/

Yes you can use mongodb as model in your project. you just have to define a model class and get the required enetities that you need.But in this you have provide an BsonId attribute for any object for generating a unique id.
here's is a example from my code just check it out.
public class QuestionAttempt
{
public ObjectId QId { get; set; }
public long UserId { get; set; }
[BsonElement("SN")]
public string SkillName { get; set; }
[BsonElement("IC")]
public bool IsCorrect { get; set; }
}
In my code i have given some objects a smaller name with the [BsonElement()] attribute for less memory usage.

Related

Mapping Parent Model To Children Models Using AutoMapper 7 / C#

I have a hierarchy of parent > children models and DTO using C# and AutoMapper 7 in a .Net Core 3 project. I am having problems mapping the parent model to the lowest child DTO.
The models involved look like this:
Parent Model #1:
public class ParentModel
{
public int Id { get; set; }
public string Title { get; set; }
public string Name { get; set; }
public string Description { get; set; }
public ICollection<MainElement> MainElements { get; set; }
public ParentElementModel()
{
MainElements = new Collection<MainElement>();
}
}
Parent Model #2 (This is actually a .Net Core Identity User but simplified for this):
public class ParentUserModel
{
public int Id { get; set; }
public string UserName { get; set; }
public string OtherData { get; set; }
}
Parent Model #3 Which is the MainElement Model which includes a CreatedBy that is of type of the ParentUserModel above:
public class MainElement
{
public int Id { get; set; }
public string Title { get; set; }
public string Description { get; set; }
public ParentUserModel CreatedBy { get; set; }
public int CreatedById { get; set; }
public string OtherData { get; set; }
}
The DTO to map are:
Most parent DTO:
public class ParentModelForReturnDto
{
public int Id { get; set; }
public string Title { get; set; }
public ICollection<MainElementForParentModelDto> MainElements { get; set; }
}
The ICollection DTO model:
public class MainElementForParentModelDto
{
public int Id { get; set; }
public string Title { get; set; }
public string Description { get; set; }
public UserCreatorForMainElementDto CreatedBy { get; set; }
}
The DTO for the CreatedBy ParentUserModel that lacks the OtherData which would be sensitive info I can't include:
public class UserCreatorForMainElementDto
{
public int Id { get; set; }
public string UserName { get; set; }
}
My problem is that the ParentModelForReturnDto's MainElementForParentModelDto's CreatedBy is coming back null when I want it to have the CreatedBy ParentUserModel's Id and Username
Here are my related mappings that don't fully map it:
CreateMap<ParentModel, ParentModelForReturnDto>();
CreateMap<MainElement, MainElementForParentModelDto>();
CreateMap<ParentUserModel, UserCreatorForMainElementDto >();
Can anyone please help me figure out how to map these so that the CreatedBy returns of type UserCreatorForMainElementDto and not null?
I believe the error to be in the mapping from MainElement to MainElementForParentModelDto but I am unsure. I have been trying for awhile to figure this out.
Any questions I can clarify. Tried to take out the unnecessary while keeping enough. Thank you to anyone who can help!
Edit:
The above mappings are using Profile.
Here is what I am mapping in my controller:
var parentModelFromRepo = _context.GetParent(name)
var parentToReturn = _mapper.Map<ParentModelForReturnDto>(parentModelFromRepo);

EF6: Using collection property without creating FK field in child table

I'm studying EF6 and think I know quite a bit already, but couldn't find a good solution (yet) for this:
Suppose I have the following model classes:
class LivingRoom {
public int Id { get; set; }
public string Name { get; set; }
public PersonTypeId { get; set; }
public IList<Person> Persons { get; set; }
}
class Person {
public int Id { get; set; }
public int PersonTypeId { get; set; }
public string Name { get; set; }
}
With these model classes I'm able to save and load via DbContext without any problem. Thanks to the navigation property in the "parent" LivingRoom class, the Persons collection will be included in this process. I don't have to load/save them separately.
UPDATE: Forgot the logical PersonTypeId field which will be used for determining which Persons should be in the collection property.
So far so good.
But EF6 is creating a FK in the Persons table, pointing to the LivingRooms table, which seems logical.
But what if I'm going to use the Persons table for a lot more other parent entities, like eg. "Bus" and "Plane", and therefore don't want to have a dependency (= FK field in LivingRooms table) in the Persons table?
Can I achieve this (don't create the FK field) without breaking the "include child list" load/save process as described?
If yes, how? And if no, why not?
NB: Please understand that I want to learn the best techniques. So good advice, to not doing this, is also welcome.
First , it's better to handle FK in Person Table ourself to do that web have this :
class LivingRoom
{
public int Id { get; set; }
public string Name { get; set; }
public IList<Person> Persons { get; set; }
}
class Person
{
public int Id { get; set; }
public string Name { get; set; }
public LivingRoom LivingRoom { get; set; }
public int LivingRoomId { get; set; }
}
now If you have others Entities Like Bus and ... so we have
public class Bus
{
public int Id { get; set; }
public ICollection<Person> People { get; set; }
}
and Updated Person class is :
public class Person
{
public int Id { get; set; }
public string Name { get; set; }
public LivingRoom LivingRoom { get; set; }
public int LivingRoomId { get; set; }
public Bus Bus{ get; set; }
public int BusId { get; set; }
}
you can set FK in Person Table as Nullable to do this :
public class Person
{
public int Id { get; set; }
public string Name { get; set; }
public LivingRoom LivingRoom { get; set; }
public int? LivingRoomId { get; set; }
public Bus Bus{ get; set; }
public int? BusId { get; set; }
}
As you can see We set BusId and LivingRoomId as nullable or you can just set one of them that you want
Note : You need to add some mapper to tell EF which field id FK and something like this ,...

Expanding classes using AutoMap

I have to import a set of data from one database to another with a somewhat different schema, and I'm considering using AutoMap. I could just write a bunch of SQL scripts, but I already have both databases in EF and I want to learn AutoMap ...
While many of the classes are similar, the problem I'm having is where the structure is really different. The target models were designed with several more layers of classes. Instead of flattening, I need to expand.
The target classes have the following properties:
public class Account
{
public int Id { get; set; }
public string Name { get; set; }
public ContactInfo Location { get; set; }
public List<Policy> Policies { get; set; }
}
public class ContactInfo
{
public int Id { get; set; }
public string Address1 { get; set; }
public string Address2 { get; set; }
public string City { get; set; }
public State State { get; set; }
public string Zip { get; set; }
public string EMail { get; set; }
public List<Phone> PhoneNumbers { get; set; }
}
public class Phone
{
public int Id { get; set; }
public string Name { get; set; }
public string Number { get; set; }
}
public class Policy
{
public int Id { get; set; }
public PolicyNumber PolicyNumber { get; set; }
public List<Transaction> Transactions { get; set; }
}
The source tables, however, are relatively flattened.
public partial class Account
{
public string AccountId { get; set; }
public string AccountName { get; set; }
public string PolicyNumber { get; set; }
}
public partial class Transaction
{
public int TransactionId { get; set; }
public int AccountId { get; set; }
public Nullable<System.DateTime> EffectiveDate { get; set; }
public string InsuredName { get; set; }
public string InsuredAddress { get; set; }
public string InsuredCity { get; set; }
public string InsuredState { get; set; }
public string InsuredZip { get; set; }
public string InsuredPhone { get; set; }
}
I can create the Map, but I don't know how to tell AutoMapper to handle converting the string Policy to a policy object and then add it to the list of Policies.
Mapper.CreateMap<Source.Account, Destination.Account>();
Even worse, the source data inexplicitly has the name and address info at the transaction level. Before you tell me that AutoMap might not be the best solution, please understand that these two source tables are 2 out of over 40 tables in this database, and that the others are not nearly as troublesome.
Can I configure AutoMap to convert the string property PolicyNumber to a Policy Object and add it to the Policies List of the target class?
Any suggestions on how I can get the name and address information from the Transaction into a ContactInfo class and add it at the Account level?
Thank you.
Thanks to Thomas Weller. Custom Value Resolvers handled exactly what I needed.

Navigate properties when using Dapper Extensions

Im using DapperExtensions library for simple CRUD operations.
When I add a navigate property to my model, I get an error message that this column is not in the database. Can you in any way change this so that Dapper Extensions ignores this property?
Example of my model
public class Order : EntityBase
{
public int OrderId { get; set; }
public int MarketId { get; set; }
public int ModelId { get; set; }
public int ContactId { get; set; }
public string Project { get; set; }
public decimal Undertaking { get; set; }
public virtual Model Model { get; set; }
public virtual Contact Contact { get; set; }
}
Use the Write attribute above the property
[Write(false)]
add the package for dapperextentions
AutoMap(); will map all other properties as long as you have the same name for the field.
public class CustomMapper : DapperExtensions.Mapper.ClassMapper<Photo>
{
public CustomMapper()
{
Table("TableName if diffrent than the Model calss name");
Map(f => f.SomePropertyIDontCareAbout).Ignore();
AutoMap();
}
}

Collection Nested within Model is Not Bound by MVC 3 (Always null)

I have a model that represents various information about a university in ASP.NET MVC 3 and Entity Framework 5.0. The model has an ICollection of another model, called TrendModel. This collection seems to never be stored/bound by MVC at any point, no matter what I do.
When I manually set this collection to something at run time (after it is retrieved from the database), the collection is of course no longer null, but whatever I seem to set it to and then store in the database, trends is always null when I retrieve it from the database.
UniversityModel:
public class UniversityModel
{
[Key]
public string univ_id { get; set; }
public string ipeds_id { get; set; }
public string name { get; set; }
public bool religious { get; set; }
#region Location Information
public string city { get; set; }
public string state { get; set; }
public string urbanization { get; set; }
public double latitude { get; set; }
public double longitude { get; set; }
#endregion
public ICollection<TrendModel> trends { get; set; }
}
TrendModel:
public class TrendModel
{
[Key]
public string id { get; set; }
public ushort year { get; set; }
public uint? capacity { get; set; }
public uint? rate { get; set; }
public uint? meals { get; set; }
public bool? forProfit { get; set; }
public bool? control { get; set; }
public string degree { get; set; }
public bool? landgrant { get; set; }
public bool? athletic { get; set; }
public string calendar { get; set; }
public bool? required { get; set; }
}
Not sure if it is relevant, but if I put in a constructor for UniversityModel that sets trends to an empty list, then trends is no longer null and is an empty list.
Is this a model binding issue, or a post issue or something? Sorry if I'm completely off-base, I'm pretty new to MVC and ASP.NET.
you haven't included a foreign key in your trend model.try adding univ_id in your TrendModel class.
public class TrendModel
{
[Key]
public string id { get; set; }
.
.
.
[ForeignKey("univ_id")]
public string univ_id {get;set;}
}
As it turn out, the issue was fixed simply by me enforcing lazy loading on the trends, so the property now reads:
public virtual ICollection<TrendModel> trends { get; set; }

Categories