I just want to get child parameters values and names in a parent class method
class Base
{
public dynamic get(//how can i get child class parameters)
{
// do something
}
}
class User:Base
{
public int id {get;set}
public string name {get;set}
public string password {get;set}
this.get( id = 5,name = "admin", password = "admin")
}
class Task:Base
{
public int id {get;set}
public string name {get;set}
this.get(id=1,name="task1")
}
I already tried with params dynamic[] values but in this case I'm getting only values but I also want names.
Can anyone guide me how can I achieve this?.
I found a solution to my problem
{
public object get(params Func<object, object>[] args)
{
// do something
}
}
class User:Base
{
public int id {get;set}
public string name {get;set}
public string password {get;set}
this.get( id => 5,name => "admin", password => "admin")
}
class Task:Base
{
public int id {get;set}
public string name {get;set}
this.get(id=>1,name=>"task1")
}```
Related
Is there any way to auto generate a constructor which looks like this:
public class User
{
public int Id { get; set; }
public string Name { get; set; }
public User(int id, string name)
{
Id = 0;
Name = "";
}
}
Currently I am creating a constructor like that with the refactoring tool (CTRL + .):
public User(int id, string name)
{
Id = id;
Name = name;
}
and editing each line afterwards which is pretty cumbersome when you have 20 properties per class. Is there a better way to that?
(Maybe to define a code snippet, so that we can somehow read the class properties with reflection and define them as snippet parameters?)
If you have a class with 20 properties, why do you need a constructor with 20 parameters? Maybe have a sense, but I usually create constructors to initialize properties that are relevant, to simplify the code, not to set all properties.
For your class, you can set the default values when you define the property and all constructors will use this values as the default.
public class User
{
public int Id { get; set; } = 0;
public string Name { get; set; } = string.Empty;
// Here you can even omit the constructor
public User()
{
}
}
Another thing that maybe useful is define a constructor with X parameters and reuse this constructor in other constructors with less parameters:
public class User
{
public int Id { get; set; }
public string Name { get; set; }
public User()
: this(0, string.Empty)
{
}
public User(int id, string name)
{
Id = id;
Name = name;
}
}
You can replace this(0, string.Empty) for this(default, default) if you want use the default value of each type.
If you need object create with default value for properties. You can code like this:
public class User
{
public int Id { get; set; } = 0;
public string Name { get; set; } = "";
}
Purpose of quick action "generate constructor" make method contructor for assign value to fields or properties. Don't use it in the case of just assigning default values.
do you mean initialize properties? Initializing properties through the code reflection mechanism also requires one-by-one assignments. For private object properties, it is necessary to de-private encapsulation. The operation of initializing properties in c# is generally to initialize object properties or object initializers in the form of constructors. Thank you hope it helps you
class Program
{
static void Main(string[] args)
{
Student student = new Student()
{
age = 25,
name = "java",
sex = "female"
};
}
class Student
{
public int age { get; set; }
public string name { get; set; }
public string sex { get; set; }
public Student()
{
}
public Student(int age, string name,string sex)
{
this.age = age;
this.name = name;
this.sex = sex;
}
}
}
I have 3 different tables and 3 different columns which are primary columns.
public class Student
{
public int StudentId { get; set; }
public string Name { get; set; }
}
public class Teacher
{
public int TeacherId { get; set; }
public string Name { get; set; }
}
public class Lesson
{
public int LessonId { get; set; }
public string Name { get; set; }
}
var _context = new MyContext()
_context.Student(x=>x.StudentId == someValue)
or
_context.Teacher(x=>x.TeacherId == someValue)
or
_context.Lesson(x=>x.TeacherId == someValue)
only changing table name and key value.
What is the best way using generic method?
Make a general repository and than inherit it with native repository of each class like this
public class GeneralRepository<T> where T : class
{
private MyContext Context = new MyContext();
protected DbSet<T> Dbset { get; set; }
public GeneralRepository()
{
Dbset = Context.Set<T>();
}
public T SelectByID(int? id)
{
var Record = Dbset.Find(id);
return (Record);
}
public class StudentRepositoy :GeneralRepository<Student>
{
}
Make a object of native repositry and call the function
Where ever you need to call the function make a object of student repository
StudentRepositoy repository = new StudentRepositoy();
var result = repository.SelectByID(3);
You can consider to use a pattern like "generic repository". Or you can simply write a method takes Expression> as input and pass the expression to it.
https://code.msdn.microsoft.com/generic-repository-pattern-ddea2262
https://www.codeproject.com/Articles/814768/CRUD-Operations-Using-the-Generic-Repository-Patte
The project I am working on use NHibernate, AutoMapper and Fluent. All I need to do is read the XML file and enter the data into database. But there is a problem I am facing. when I try to map the Source and Destination I get the error which I have mentioned in the title.
Below is my code:
public partial class Language
{
public string languageIdField;
public string languageNameField;
}
public partial class Person
{
public int personIdField;
public string firstNameField;
public string lastNameField;
public int stateField;
public int enableEmailField;
public int attestPersonLockedField;
public string emailAddressField;
public string languageId;
}
I am creating above classes with xsd2code tool.But I have simplified it here.
Model classes are:
public class Person
{
public virtual string FirstName { get; set; }
public virtual string LastName { get; set; }
public virtual string EmailAddress {get; set;}
.....
public int state {get; set;}
public virtual User User { get; set; }
public virtual Language language { get; set; }
}
public class Language
{
public virtual string LanguageId { get; set; }
public virtual string LanguageName { get; set; }
public virtual IList<Person> Persons { get; set; }
}
And this is how I map them with AutoMapper:
AutoMapper.Mapper.CreateMap<Language, Models.Language>();
AutoMapper.Mapper.CreateMap<Person, Models.Person>();
And that's how I am reading and trying to save the data:
object id = null;
foreach (var item in templateData.Languages)
{
id = save<Dicom.Expense.Models.Language>(item); // this will return the language id
}
Person person = new Person();
person.Emailaddress = templatedata.Person.EmailAddress;
....
person.languageId = id.ToString();
save<Dicom.Expense.Models.Person>(person);
private void save<TModel>(object templateObject)
{
var dbModel = AutoMapper.Mapper.Map<TModel>(templateObject);
repository.Save<object>(dbModel);
}
When I try to save the Person information I get the error:
could not execute batch command.[SQL: SQL not available]
Cannot insert the value NULL into column 'fkLanguageID
And this is because the Person table have the language ID as a foreign key in it. Now I do not know what changes I need to do so that Person source and destination map properly and save the data into database.
EDIT:
I have realized that I need to change the Person.languageId value into PersonModel.Language object so that NHibernate can read it and map it. Is it possible to use Customer Resolver or Type Converter to achieve this?
This is what I am trying to do:
AutoMapper.Mapper.CreateMap<Person, Models.Person>().ForMember(dest => dest.Language, opt => opt.ResolveUsing<CustomResolver>());
public class CustomResolver : ValueResolver<Person, Models.Language>
{
public Dicom.Expense.Models.Language ResolveCore(Person source)
{
?????
}
}
I solved the problem by creating a Resolver which AutoMapper provide for complex mapping. While creating a mapping I told the mapper to resolve the Destination Language with Source Language ID by resolving it into an object of type Language.
Below is my code;
AutoMapper.Mapper.CreateMap<Person, Models.Person>()
.ForMember(x => x.Language, opt => opt.ResolveUsing(new LanguageCodeResolver(loadRepository)).FromMember(x => x.LanguageId));
public class LanguageCodeResolver : ValueResolver<string, Dicom.Expense.Models.Language>
{
private IDatabaseLoadRepository loadRepository;
public LanguageCodeResolver(IDatabaseLoadRepository loadRepository)
{
this.loadRepository = loadRepository;
}
protected override Models.Language ResolveCore(string languageCode)
{
return loadRepository.FindOne<Models.Language>(x => x.LanguageId == languageCode);
}
}
So there is a way to map 2 hierarchical classes in EF to the same table with a defining column and value (http://msdn.microsoft.com/en-us/data/jj591617.aspx#2.4). I am wondering if there's a way to map 2 non-hierarchical classes to the same table in the same manner.
Example:
class User
Guid Id
string Name
Guid? GroupId
class Group
Guid Id
string Name
Table
uid Id PK
varchar Name
bit IsGroup
uid GroupId nullable
I can't change the schema of that table, so the only solution I've come up with so far is to create a view for User and a view for Group.
Mo,
I think that at the end of the day you are after a user group that contains the users that belong to it. If that's the case here is something that will get you started. Remember that this is not meant to be a "best practice" just an example to get you up and running. you will need to tweak this code for your exact situation.
Here's the basic jest of it. You need to give group a property of type List...then the populate the list of users from a database query. In the below example I wrote a method that handles populating the list. However in practice you don't have to do populate the list here you could instantiate the userGroup and populate the list of users from inside an action method. Like I said this in not a best practice just a quick example.
Here is an example.
public class userGroup
{
class user
{
private int id { get; set; }
private string name { get; set; }
private Guid grpId { get; set; }
public int userId { get { return id; } set { id = value; } }
public string userName { get { return name; } set { name = value; } }
public Guid groupId { get { return grpId; } set { grpId = value; } }
public user() { }
}
class group
{
private Guid id { get; set; }
private string name { get; set; }
public List<user> usersInGroup = new List<user>();
public Guid groupId { get { return id; } set { id = value; } }
public string groupName { get { return name; } set { name = value; } }
public group() { }
}
public userGroup() { }
public group getUserGroup()
{
group x = new group();
Guid newGroupId = Guid.NewGuid();
x.groupId = newGroupId;
var userQuery = myDB.Where(n => n.myField == myConditon).Select(n => new
{
n.userId,//I'm assuming that the database query returns a field userId
n.userName//I'm assuming that the database query returns a field userName
});
foreach(var user in userQuery)
{
userGroup.user y = new userGroup.user();
y.groupId = newGroupId;
y.userId = user.userId;
y.userName = user.userName;
x.usersInGroup.Add(user);
}
return x;
}
}
I hope that I understood your question and that my example points you in the right direction.
Best wishes,
Bill
You can pretty easily model this by introducing an abstract base type from which both types derive.
public abstract class BaseNamedEntity
{
public Guid Id { get; set; }
public string Name { get; set; }
}
public class Group : BaseNamedEntity
{
public virtual ICollection<User> Users { get; set; }
}
public class User : BaseNamedEntity
{
public Guid GroupId { get; set; }
public virtual Group Group { get; set; }
}
In the context you tell that IsGroup is the discriminator:
public class MyContext : DbContext
{
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<BaseNamedEntity>().ToTable("MyTable");
modelBuilder.Entity<Group>().Map(m => m.Requires("IsGroup")
.HasValue(true));
modelBuilder.Entity<User>().Map(m => m.Requires("IsGroup")
.HasValue(false));
}
public DbSet<BaseNamedEntity> BaseNamedEntities { get; set; }
}
I don't think that BaseNamedEntity is a particularly good name, so maybe you have to come up with something more meaningful.
Is there any way to access the Class and Property name which you attached an attribute to inside the attribute?
For example
public class User {
public string Email { get; set; }
public string FirstName { get; set; }
[MyAttribute]
public string LastName { get; set; }
}
And then in the MyAttribute class
public class MyAttributeAttribute {
public MyAttributeAttribute () : base() {
string className = /*GET CLASS NAME - should return "User" */
string propertyName = /*GET PROPERTY NAME - should return LastName*/
}
}
I know I can pass in the information in the constructor, but hoping there is an easy way somehow to save on retyping info over and over again either via reflection or...
Sorry, but no that's not possible. You could also have
public class User {
public string Email { get; set; }
public string FirstName { get; set; }
[MyAttrubute]
public string LastName { get; set; }
}
[MyAttrubute]
public class OtherClass {
[MyAttrubute]
public string AnotherProperty { get; set; }
}
The attribute can be created from anywhere. Even the following is a valid way to create an instance:
var att = new MyAttribute();
Your question could be boiled down to "Can I detect where my custom class is instantiated from?". In my last example, StackTrace could probably be used. But with attributes they are being constructed by the .NET runtime, so you would not be able to go that route.