What is the corresponding SSRS Query to be used in the designer ?
The parameter is an object in C# as so
public class A
{
[MessageBodyMember]
public Dictionary<string, string> Parameters { get; set; }
}
The problem is with the Dictionary
Related
I have a quite big query in my WebApi which filters data from different models to send them in a DTO Object to FrontEnd(Angular).
I think DTO could be the right approach because it isn't neccessary for the frontend to get all parameters from all models.
My problem consists in from mapping the DTO Object back to my WebApi Models.
I tried Automapper from NugetPackages but it didn't work. I also heard that AutoMapper isn't the right choice when projects are getting bigger and bigger.
Below is the Code for my DTO object, query and models:
public class ApplicationSettingsDto
{
public string KeyName { get; set; }
public string Wert { get; set; }
public string DefaultValue { get; set; }
public string Description { get; set; }
}
Models:
public partial class ApplicationSettings
{
public string KeyName { get; set; }
public string Wert { get; set; }
public int Typ { get; set; }
public string DisplayOrder { get; set; }
}
public partial class ApplicationSettingsDefaults
{
public Guid Id { get; set; }
public string KeyName { get; set; }
public string Value { get; set; }
public int ProduktOption { get; set; }
}
public partial class Text
{
public string KeyName { get; set; }
public string Sprache { get; set; }
public string Text1 { get; set; }
public DateTime LetzteAenderung { get; set; }
}
Query:
public IQueryable Description()
{
int produktOption = GetProduktOption();
var query = from appl in _repositoryContext.ApplicationSettings
from text in _repositoryContext.Text
from defaults in _repositoryContext.ApplicationSettingsDefaults
//filter DefaultValues
where appl.KeyName.Equals(defaults.KeyName) &&
(defaults.ProduktOption.Equals(produktOption) || defaults.ProduktOption.Equals(65535))
//Filter TextValues
where EF.Functions.Like(text.KeyName, "%" + appl.KeyName) ||
EF.Functions.Like(text.KeyName, "%" + appl.KeyName + "$Descr")
where EF.Functions.Like(text.Sprache, "de-DE")
select new ApplicationSettingsDto()
{
KeyName = appl.KeyName,
Wert = appl.Wert,
DefaultValue = defaults.Value,
Description = text.Text1
}
into output orderby output.KeyName select output;
return query;
}
So this question is not about an detailed implementation, it's only about recommendations for implementing DTO because mapping can be a pain in the *ss, like in my example.
I'm open to new ideas or patterns I don't know yet to try to manage problems like this.
Thanks in Advance ;)
This question is likely to be closed as you have working code, but my recommendation, after years of having tried AutoMapper, reflection based mappings, and hand-written mappings, that you should just stick with what is simplest and works.
You typically have to write the mapping logic for your DTOs once. The code you would write is legible and straightforward. When you move that to AutoMapper, you now end up having an often unrelated and less legible piece of code for something very, very simple.
In the event that you need the mapping logic in another function, extract it to a separate method. In the event that you need it in a separate class, promote that mapping function to a static method on your DTO.
Most of my mapping code looks like:
// Some controller code
da.GetStudents().Select(Map); // Map is the function below
In the controller, the following method is defined:
public StudentDto Map(Student student)
{
if (student == null) return null;
return new StudentDto
{
FirstName = student.FirstName,
...
};
}
Hope that helps.
I am using "CodeFirst Existing Database" and have introduced a stored procedure from mycontext class which seems fine but the entity i am mapping to has a complex type.
MyContext
public virtual List<Student> Get_AllStudents(int year, string classes, string indicators) {
StringBuilder spCommand = new StringBuilder();// = "CALL Get_AllStudents(";
//params object[] parameters;
MySqlParameter[] mySqlParams = new MySqlParameter[]{new MySqlParameter("yearId", year),
new MySqlParameter("classIds", classes),
new MySqlParameter("indicatorList", indicators)};
spCommand.Append("CALL Get_AllStudents(#yearId,#classIds,#indicatorList);");
return this.Database.SqlQuery<Student>(spCommand.ToString(), mySqlParams).ToList<Student>();
}
and my query is
select s.firstname, s.surname,s.IndicatorID from students s
where ClassId in (classIds)
and yearId = yearId
and indicatorId in (indicatorList);
My Student Entity has a complex type "Name"
public class Student
{
public int studentID { get; set; }
public string studentCode { get; set; }
public Name name { get; set; }
public Nullable<System.DateTime> birthdate { get; set; }
}
public class Name {
[Column("surname")]
public string surname { get; set; }
[Column("middlename")]
public string middlename { get; set; }
[Column("firstname")]
public string firstname { get; set; }
[Column("preferredname")]
public string preferredname { get; set; }
}
How do i tell entity framework to map s.firstname and s.surname to map to Student.Name.firstname and Student.Name.surname properties
I havent used import function (as it is giving me some stupid error i dont want to deal with "Your project references the latest version of EntityFramework however EF data provider compatible with this version cannot be found...") can i change some sp settings in mycontext class to expect complex type?
Error
Cannot create a value for property 'name' of type 'DbContexts.Name'.
Only properties of primitive or enumeration types are supported.
I came across this problem where I should allow different sets of validation when saving a model. Usually the validation depends on how the user wants to save the data. For example, if the user wants to save his data as "Draft", I should allow some fields to be blank. If not "Draft", I should put more restrictions.
class Form
{
public int ID { get; set; }
[Required("Title is required.")]
public string Title { get; set; }
[Required("Body is required.")]
public string Body { get; set; }
public bool IsDraft { get; set; }
}
In the code above, I want the validation for body to work only if IsDraft is false.
How do you create multiple sets of validation? Or how to properly create conditional validation in Entity Framework?
Data annotations are not only used for validation but also to make your code in sync with the database. I.e. in EF Code First, if you remove Required field, then your database must allow NULL to be inserted in matching column.
Therefore you can do the following approach:
Create your entity model class to have as lowest requirements as possible
Create your view/DTO model class that will implement IValidatableObject interface
Implement IValidatableObject interface and do conditional validation there
IValidatableObject interface allows your class to be used by Validator (MSDN on Validator) from System.ComponentModel.DataAnnotations namespace, in the same way the validation is done via annotation attributes.
Interface implementation should look like this:
public class FormDto: IValidatableObject
{
public int ID { get; set; }
[Required("Title is required.")]
public string Title { get; set; }
[Required("Body is required.")]
public string Body { get; set; }
public bool IsDraft { get; set; }
public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
{
if(!IsDraft && string.IsNullOrWhiteSpace(Body)) yield return new ValidationResult("Body is required.", new string [] {"Body"});
if(!IsDraft && string.IsNullOrWhiteSpace(Title)) yield return new ValidationResult("Title is required.", new string [] {"Title"});
}
}
If your view / DTO model is going through i.e. MVC pipeline, this interface will be invoked automatically. If from any reason you notice it is not invoked (I don't know the structure of your solution), you can plug this code somewhere in your process pipeline and it will invoke validation / throw exception:
public static class IValidatableObjectExtensions
{
public static void SelfValidate(this IValidatableObject model)
{
ValidationContext ctx = new ValidationContext(model);
Validator.ValidateObject(model, ctx, true);
}
}
Using C#, ASP .Net MVC 4, Entity Framework 5 and Database First. How can I override a property or add a new property to a model class? Below you can see the "Type" as a Byte, but I can't display the byte to the users and I want to display a friendly name. The Type description is not in the database, it is stored in a dictionary.
namespace Cntities
{
public partial class myClass
{
public int Id { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public byte Type { get; set; }
}
}
Since the class is a partial you can expand and add your own properties and methods just ensure its defined in the same location as your current partial file.
namespace Cntities
{
public partial class myClass
{
public string DisplayValue{ get {
return "Formated"; // An example
}
}
}
Take a look at http://msdn.microsoft.com/en-us/library/wa80x488.aspx
I have a class that I want to keep meta data for -- there a several interaction scenarios so meta allows me to keep different meta for different interaction types.
class Feed()
{
Guid FeedId { get; set; }
ObjectMetaDictionary Meta { get; set; }
}
I would like EF to serialize this ObjectMetaDictionary and store it as a string/VarChar in the database. When I retrieve a record I want it to be deserialized as an ObjectMetaDictionary.
Does EF support this? How can I do it?
I am using Entity Framework Code First.
SOLVED: I provided an answer below that solved my problem. I will accept this answer as soon as SO allows me to.
Apparently this is actually quite easy. I was able to get it working thanks to some help from this previous SO answer.
Fluent configuration in OnModelCreating allows us to tell EF what to use as the value property for serializing to the DB and back out again.
Here's my solution:
public class Feed
{
public virtual Guid FeedId { get; set; }
public virtual FeedMetaData Meta { get; set; }
public virtual string Title { get; set; }
public virtual string Description { get; set; }
}
public class FeedMetaData
{
public Dictionary<string, string> Data { get; set; }
public string Serialized
{
get { return JsonConvert.SerializeObject(Data); }
set
{
if(string.IsNullOrEmpty(value)) return;
var metaData = JsonConvert.DeserializeObject<Dictionary<string, string>>(value);
Data = metaData ?? new Dictionary<string, string>();
}
}
// addl code removed...
}
public class FeedsDbContext : DbContext
{
public DbSet<Feed> Feeds { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.ComplexType<FeedMetaData>()
.Property(p => p.Serialized)
.HasColumnName("Meta");
modelBuilder.ComplexType<FeedMetaData>().Ignore(p => p.Data);
base.OnModelCreating(modelBuilder);
}
}
Have your Entity Framework object be simple and have a String property for the column in the database.
class Feed()
{
Guid FeedId { get; set; }
String Meta { get; set; }
}
Create methods that save and load the property as such: (it's been a while since I've used EF, so i'm not sure if you can create a transient property with these getter/setters or if you need something else)
//Reading from string column Meta
(ObjectMetaDictionary) XamlServices.Load(new StringReader(someFeed.Meta));
//Saving to string column Meta
someFeed.Meta = XamlServices.Save(value);
This brings another whole issue to your project though. Changing your ObjectMetaDictionary might cause it to not deserialize from the database correctly. Your ObjectMetaDictionary becomes essentially part of your database schema and you will need to handle versioning or changes accordingly.
The feature HasConversion saved my life. Unlock all json formats! Enjoy it!
public partial class Feed
{
public int Id { get; set; }
//this column will be mapped to a "nvarchar(max)" column. perfect!
public Dictionary<string, string> Meta { get; set; }
}
public class FeedsDbContext : DbContext
{
public FeedsDbContext(DbContextOptions<FeedsDbContext> options)
: base(options)
{
}
public virtual DbSet<Feed> Feed { get; set; }
protected override void OnModelCreating(ModelBuilder builder)
{
base.OnModelCreating(builder);
builder.Entity<Feed>(entity =>
{
entity.Property(p => p.Meta).HasConversion(
x => JsonConvert.SerializeObject(x) //convert TO a json string
, x => JsonConvert.DeserializeObject<Dictionary<string, string>>(x) //convert FROM a json string
);
});
}
}