Is it possible to convert an IDictionary into a class?
My IDictionary looks like this
{{DapperRow,
Date = '9/25/2014 12:00:00 AM',
UserId = '123456',
User = 'Timothy'
}}
my class
public class MyClass
{
public DateTime Date {get; set;}
public string User {get; set;}
public int UserId {get; set;}
public virtual someModel {get; set;}
}
To convert the dictionary you provided to the class you provided, you can just add a constructor to the model class to read the dictionary values.
public class MyClass
{
public DateTime Date { get; set; }
public string User { get; set; }
public int UserId { get; set; }
public MyClass(IDictionary<string, object> data)
{
Date = DateTime.Parse(data["Date"].ToString());
User = data["User"].ToString();
UserId = int.Parse(data["UserId"].ToString());
}
}
But Panagiotis is right, in this situation you should be taking advantage of dapper to automagically map data to your models for you. Their readme is incredibly helpful if you need to figure out how it works or how to do complex mappings.
Related
I am trying to query and have the navigational property (the list) return with the correct number of items in it. Currently what I am doing, the list is always empty (Case_Users property in Case object for the example below) when it should not be.
I have these classes:
public class Case
{
public Case()
{
Create_Date = DateTime.Now;
}
[Key]
public int Id { get; set; }
[MaxLength(1000)]
public string CaseNumber { get; set; }
public ICollection<Case_Users> Case_Users { get; set; } = new List<Case_Users>();
}
public class Case_Users
{
public Case_Users()
{
Create_Date = DateTime.Now;
}
[Key]
public int Id { get; set; }
[ForeignKey("Case")]
public int CaseID { get; set; }
public Case Case { get; set; }
public string Role {get; set;}
}
I want to make it so that I can query using the method syntax, starting with the Case and using its navigational property to get the data from its Case_Users navigational property entries, like this:
var query = _context.Case.Include(c => c.Case_Users).ToList();
I am getting simply my list object returned, but the Case_Users list object is empty. Even though it should not be.
Is it possible to query based on the navigational property, and if so what is the syntax?
I need to audit data in some tables in my server database so my clients can take partial updates (by table/entity). Data in the server database is only edited from the server website.
The audits will be requested by a client: WHERE Id > [Clients Last Id], the server will then do some processing and then return the latest audits to keep themselves up to date.
I can't seem to get to a generic pattern that will work across the board for all of my models:
public class Domain {
public int Id { get; set; }
public string Property1 { get; set; }
public int Property2 { get; set; }
}
Then I think I want to be able to do something like so:
public class DomainContext : DbContext {
public DbSet<Domain> Domain { get; set; }
public DbSet<History<Domain>> DomainHistory { get; set; }
}
This is my problem class taking this route, I want to inherit from Domain so things like property changes and EF migrations (in code first) will 'just work'. But I Cannot derive from 'T' because it is a type parameter
public class History<T>
: T //Cannot derive from 'T' because it is a type parameter
where T : class {
public DateTime CreatedOn { get; set; }
public int CreatedByUserId { get; set; }
public int EntityFK { get; set; }
// This will always be the current version
//public T Entity { get; set; }
// I could store a snapshot of the state at the time of the audit
public string XMLData { get; set; }
}
I don't know if my use of generics is warranted here but I'm basically trying to get to a point where I can do the below so my models play nicely with EF Migrations:
Domain d = GetDomainModel();
History<Domain> dh = new History<Domain>();
dh.Property1 = d.Property1;
dh.Property2 = d.Property2;
How can this be done?
For a basic audit of your entities you can use a base class and intercept the changue type in a override of savechangues in context, like this (sorry of format, i write in mobile):
public class AuditBase
{
//Adapt your requirements, the propertys are exists in db
public datetime creationdate { get; set; }
public datetime modificationdate { get; set; }
public string creationuser { get; set; }
public string modificationuser { get; set; }
}
public class ModelBBDD : AuditBase
{ }
You can override the SaveChanges method of Context. In the method, you can through the ChangueTracker property of Database Class for added or updates dto's, like this:
var dto = entity as auditbase;
if (dto == null) continue;
if (dto.state == entitystate.added)
{
((Auditbase)entity).creationdate = datetime.now;
((Auditbase)entity).creationuser = environment.username;
}
else if( dto.state == entitystate.modified)
...
...
If you can log all the changues of properties, you can trough all the properties of dto with reflection and type in SaveChanges, and save values in log.
I feel like this is going to be very obvious to many of you, but my research led me nowhere.
I'm trying to build a class that will create objects with a list of properties like this one:
public class MyObject
{
[Key]
public int Id { get; set; }
public string Title { get; set; }
public List<OpenHours> OpenHours { get; set; }
public Filter Filters { get; set; }
}
I want the OpenHours object to store a list of daily hours so that they are accessible by doing MyObject.OpenHours[index].property.
I'm currently getting the error that the OpenHours object does not have a defined key, but I actually don't want it to be in my database as a different entity, I just want it to store properties the same way that it would if I listed each of the weekDay's properties directly in the MyObject class.
Here is the OpenHours class:
public class OpenHours
{
public DayOfWeek Day { get; set; }
public string StartTime { get; set; }
public string EndTime { get; set; }
}
I want each of my "MyObject" objects to have unique OpenHours values, so I do not want to create an Id just for it.
Am I missing something in the syntax, or is it bad logic to do so?
Thanks in advance for your answers!
Edit: Someone answered and deleted his answer afterwards, so I can't mark it as the right answer, but the solution was to add [ComplexType] to my class :
[ComplexType]
public class OpenHours
{
public DayOfWeek Day { get; set; }
public string StartTime { get; set; }
public string EndTime { get; set; }
}
if each entry is going to be unique then make a compound primary key if you do not want to introduce an id. Make all the properties the primary key. This will be less efficient in DB terms than just creating an Id as the primary key though.
Someone answered and deleted his answer afterwards, so I can't mark it as the right answer, but the solution was to add [ComplexType] to my class :
[ComplexType]
public class OpenHours
{
public DayOfWeek Day { get; set; }
public string StartTime { get; set; }
public string EndTime { get; set; }
}
Links for additional information on Complex Types:
Associations in EF Code First: Part 2 – Complex Types
Entity Framework Complex Types - EF Designer
Hello I have problems with my foreign key declaration.
App compile but i cant do "add-migration" because of an error:
The ForeignKeyAttribute on property 'TypeId' on type 'Equipment.Models.Device' is not valid. The navigation property 'DeviceDictionaryId' was not found on the dependent type 'Equipment.Models.Device'. The Name value should be a valid navigation property name
Here You can see my code:
namespace Equipment.Models
{
public class Device
{
public int DeviceId { get;set; }
[Required]
[StringLength(14)]
public string DeviceUser { get; set; }
[ForeignKey("DeviceDictionaryId")]
public int TypeId { get; set; }
}
public class DeviceDBContext: DbContext
{
public DbSet<Device> Devices {get; set;}
}
}
and second class:
namespace Equipment.Models
{
public class DeviceDictionary
{
public int DeviceDictionaryId { get; set; }
[Required]
public string DeviceManufacturer { get; set; }
[Required]
public string DeviceName { get; set; }
}
public class DeviceDictionaryDBContext : DbContext
{
public DbSet<DeviceDictionary> Dictionary { get; set; }
}
}
Can anyone suggest me needed edits?
You're creating two separate DbContext objects. Try adding just one:
public class MyDbContext: DbContext
{
public DbSet<Device> Devices {get; set;}
public DbSet<DeviceDictionary> Dictionaries { get; set; }
}
The Context must reference both Classes so that it knows about their existence. This way it can do its work, that is, set references between those classes using foreign keys.
Try this...
namespace Equipment.Models
{
public class Device
{
public int DeviceId { get;set; }
[Required]
[StringLength(14)]
public string DeviceUser { get; set; }
[ForeignKey("DeviceDictionaryId")]
public int DeviceDictionaryId { get; set; }
}
public class DeviceDBContext: DbContext
{
public DbSet<Device> Devices {get; set;}
}
}
Name the property DeviceDictionaryId as opposed to TypeId to allow The EF Conventions to do their work!
EDIT:
Just noticed after seeing the other answer that you have two seperate DBContext's!
I believe you need to change
[ForeignKey("DeviceDictionaryId")]
public int TypeId { get; set; }
to
[ForeignKey("DeviceDictionary")]
public int TypeId { get; set; }
... in other words, the annotation needs to specify the table rather than the column.
As others pointed out, you only need a single DBContext, with one DbSet for each table.
I have a class, "Search". See definition below:
public class Search
{
[Key]
public int SearchID { get; set; }
public int UserID { get; set; }
public SearchParameters SearchParameters { get; set; }
public ICollection<SearchProvider> SearchProviders { get; set; }
public User User;
}
SearchParameters is a class with value types, and a few sub-classes; as defined below:
public class SearchParameters
{
public List<string> SearchTerms { get; set; }
public int MaxRecords { get; set; }
public DistanceParameter Distance { get; set; }
public PriceRangeParameter PriceRange { get; set; }
}
The idea is that I do not want a separate SearchParameters table that has to link to the Search table because every property of the search is always one to one (Except for SearchTerms). Really, what I want EF to do is 'bring up' the child classes' properties so we end up with All the properties of SearchParameter in the SearchTable (and all the parameters of the DistanceParameter and PriceRangeParameter objects themselves). What annotations or other logic would I need for this to work? Thanks!
I think EF Complex Type mapping is what you need, see more here:
http://weblogs.asp.net/manavi/archive/2011/03/28/associations-in-ef-4-1-code-first-part-2-complex-types.aspx