using a class name in another class property.? [duplicate] - c#

This question already has answers here:
virtual properties
(7 answers)
Closed 7 years ago.
I am pretty new to C#. I have two classes a Movie class and a Genre class.I cant understand the property "public virtual Genre Genre" Could someone explain me this? Following are the two classes
public class Genre :IEntityBase
{
public Genre()
{
Movies = new List<Movie>();
}
public int ID { get; set; }
public string Name { get; set; }
public virtual ICollection<Movie> Movies { get; set; }
}
public class Movie:IEntityBase
{
public Movie()
{
Stocks = new List<Stock>();
}
public int ID { get; set; }
**public virtual Genre Genre { get; set; }**
public virtual ICollection<Stock> Stocks { get; set; }
}

public virtual Genre Genre { get; set; } means the following:
Declare a property named Genre (the second occurrence)
This property is of type Genre (the first occurrence)
This property can be read (get) and can be changed (set).
This property can be read or set by any other class in any other library that has access to this object (public)
This property can be overridden (have it's code replaced to do something different) by a subclass. (virtual).

The type and the name are Gender which to you might look confusing but for the computer it's like this:
a bunch of modifiers like public, private etc. + the type + the name
So it actually doesn't consider the second Gender as a type because it's just a name for something. Under the hood, it's not referring to the variable/properties you create by their name anyway. It uses some kind of pointer or reference.
Now, if you mean to ask how to interpret that particular definition, it says that the property is supposed to be seen outside the class (it's not hidden/private). It's also possible to alter its meaning if you use inheritance. It will return something of type Gender (the class) and it's name is Gender (and it could be called almost anything, if you wish). I t also says that it will work as a container for that Gender-like value and you can freely assign it and read it.
Most of the details are of importance and can be seen to modify the behavior when you start using the instances of it in a bigger scope. Just in this example, it's really no difference if you go public or virtual. Did it help?

Related

Keeping consistent property names in dynamic objects?

So, I'm not sure where my head is at today but I can't wrap my head around a decent solution to this issue and I was hoping you guys can help.
We are building a .NET Core / EF Core / SQL application that hands a base record type, and then we layer on metadata objects on top of that base record to enrich the datasets. So my base class looks something like this:
public class Record
{
[NotNull]
public Guid Id { get; set }
[CanBeNull]
public virtual string InvoiceNum { get; set; }
[CanBeNull]
public virtual string Notes { get; set; }
//Enum that defines the extra properties
public virtual RecordType RecordType { get; set; }
public Dictionary<string,object> ExtraProperties { get; set; }
}
and my MetaData class looks something like this:
public class MetaData
{
[NotNull]
public Guid Id { get; set; }
[NotNull]
public Guid RecordId { get; set; }
[NotNull]
public virtual string Description { get; set; }
//Enum that defines the extra properties
public virtual MetaDataTypes MetaDataType { get; set; }
public Dictionary<string,object> ExtraProperties { get; set; }
}
I am using the ExtraProperties field in each object to store a JSON encoded string of additional data for each type, determined by the Enum values noted in the objects above.
What I am trying to find out, is how do I consistently (and efficiently) define those metadata fields on an incoming JSON without needing to hard code each individual type?
For example, I was thinking the JSON for a complete incoming record could be something like this:
{
"Record" : {
"InvoiceNum":"12345",
"Notes":"Notes go here",
"MetaData" : [
{
"MetaDataType" : "Address",
"Properties" :
{
"Address01":"123 ABC Ave",
"City":"New York City",
"Country":"US"
}
},
{
"MetaDataType":"ClientContact",
"Properties" :
{
"FirstName":"John",
"LastName":"Doe",
"Email":"jdoe#example.com",
"Phone":"8675309"
}
}]
}
}
But I want the "Properties" objects to have consistent values based on what the MetaDataType object is defined as and I only want to store the properties for that particular object type in the database attached to that object (there are, across all metadata types, about a hundred unique values).
Hopefully that makes sense, like I said earlier my brain is fried a little today so maybe I am missing something really obvious, but I would like to get your thoughts.

Cannot implicitly convert type 'System.Collections.Generic.List<MODEL#1>' to 'System.Collections.Generic.List<Model#2>

I'm using MVC5 with EF6 .I'm getting the below conversion Error
Cannot implicitly convert type
System.Collections.Generic.List<TreaceabilitySystem.GLB_M_PROFITCENTER>
to
System.Collections.Generic.List<TreaceabilitySystem.Models.Profitcenter>
private TSEntities db = new TSEntities();
// GET: Profitcenter
public ActionResult Index()
{
List<Profitcenter> profitcenter = new List<Profitcenter>();
profitcenter = db.GLB_M_PROFITCENTER.ToList(); //Error coming up here
return View(profitcenter.ToList());
}
My models are here:
This Model created through EF when i add table in .edmx
public partial class GLB_M_PROFITCENTER
{
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")]
public GLB_M_PROFITCENTER()
{
this.GLB_M_USERMASTER = new HashSet<GLB_M_USERMASTER>();
}
public string PROFITCENTER_CODE { get; set; }
public string PROFITCENTER_NAME { get; set; }
public string DESCRIPTION { get; set; }
public bool ISACTIVE { get; set; }
public int CREATEDBY { get; set; }
public System.DateTime CREATED_DATE { get; set; }
public Nullable<int> UPDATEDBY { get; set; }
public Nullable<System.DateTime> UPDATED_DATETIME { get; set; }
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
public virtual ICollection<GLB_M_USERMASTER> GLB_M_USERMASTER { get; set; }
}
And I have created the below model for change the display name and validation purposes
[MetadataType(typeof(Profitcenter))]
public partial class GLB_M_PROFITCENTER { }
public class Profitcenter
{
[Required(ErrorMessage = "*")]
[DisplayName("Profitcenter Code")]
public string PROFITCENTER_CODE { get; set; }
[Required(ErrorMessage = "*")]
[DisplayName("Profitcenter Name")]
public string PROFITCENTER_NAME { get; set; }
[DisplayName("Description")]
public string DESCRIPTION { get; set; }
[DisplayName("Is Active")]
public bool ISACTIVE { get; set; }
[DisplayName("Created By")]
public int CREATEDBY { get; set; }
[DisplayName("Created Timestamp")]
public System.DateTime CREATED_DATE { get; set; }
[DisplayName("Upated by")]
public Nullable<int> UPDATEDBY { get; set; }
[DisplayName("Updated Timestamp")]
public DateTime UPDATED_DATETIME
{
get; set;
}
}
both models are exactly same , Am I missing anything ?
How do I fix this?
both models are exactly same
That doesn't mean you can just assign the one to the other. For this code to work:
Foo foo = new Foo();
Bar bar = foo;
Bar must be a base type of Foo. This isn't the case here, both your Bar and Foo just happen to have the same property names.
You need to map from one to the other:
public Profitcenter Map(GLB_M_PROFITCENTER input)
{
return new Profitcenter
{
PROFITCENTER_CODE = input.PROFITCENTER_CODE,
...
};
}
You can do the mapping of the entire list with Select():
List<Profitcenter> profitcenter = new List<Profitcenter>();
profitcenter = db.GLB_M_PROFITCENTER.Select(Map).ToList();
An automated way of doing this could be using AutoMapper, which works especially well if all properties on both sides are named identically.
That only answers your question partially though. You have two types: GLB_M_PROFITCENTER, an Entity Framework-generated class that represents a database table, and Profitcenter, where you have added attributes that can be used for input validation using the MetadataType attribute.
I'm not a fan of the latter, because you're then using Entity Framework models as viewmodels for your UI layer. You shouldn't, and you can just remove the MetadataType attribute from the partial class definition.
So you can either use the MetadataType, but then never really instantiate that type (after all, it is a metadata type):
List<GLB_M_PROFITCENTER> profitcenter = db.GLB_M_PROFITCENTER.ToList();
return View(profitcenter);
And make your view #model IEnumerable<GLB_M_PROFITCENTER>. Then MVC will read the MetadataType attribute for GLB_M_PROFITCENTER, and apply the metadata (DisplayName, ...) as applied to Profitcenter (but you shouldn't).
Or you can simply apply mapping, thereby decoupling your view model from your entity model (and thus your database), with all additional benefits.
Some programming languages, unlike C# and other C-like languages, allow for what is called "duck typing", which would let you assign from different types if they both "quack the same way".
In C#, however, you can only assign an instance of a class to a variable of the same type, or of a base type (a class which your class extends, or an interface which it implements). Even if you had two classes which looked exactly the same, you wouldn't be able to assign from one of them to the other. .NET prior to version 4.0 didn't even support proper generic covariance and contravariance, meaning you couldn't even assign a IEnumerable<Tderived> to IEnumerable<Tbase> even if Tderived is derived from Tbase.
The solution could be to:
use a tool which will map from one class to the other (i.e. copy between equally named properties), like AutoMapper, or
redesign your app to have a separate assembly which contains common entities to be shared between other assemblies type (not a bad idea either), or
extract an interface so that you can assign to this base interface.
It is not uncommon to use mapping to resolve this issue, since you often want to have plain data transfer objects for moving data between tiers, so using an automated tool for this is ok, but if you can keep all entities in a separate assembly which is referenced by both DAL and business layer, but doesn't know anything about them, then it's an even better approach because it avoids any runtime mapping issues.
GLB_M_PROFITCENTER and Profitcenter are not same types, you just share metadata for sharing of attributes from viewmodel to entity model. You should use linq projection for conversion of one type to other
db.GLB_M_PROFITCENTER.select(e => new Profitcenter() {
/* props mapping*/
}).ToList()
you can also use mapping engine for example AutoMapper
If the member names are the same - use auto mapper - it will automatically convert each type.
Mapper.CreateMap<SourceType, DestinationType>()
Then you can call
Mapper.Map<DestinationType>(instanceofSourceType);

Making a class member array of objects in Python3

I'm trying to create 3 custom classes in Python:
One for a "Property"
One for a "Building"
One for a "Tenant"
In reality, a property can have multiple buildings on it, and each building can have multiple tenants. So, in trying to code that in Python, I haven't found a clear way to have a class member variable which is an array of objects of the other classes' type. In C# I did it using C# Lists, as follows:
public class Property
{
public string Name { get; set; }
public List<Building> Buildings = new List<Building>();
}
public class Building
{
public string Name { get; set; }
public List<Tenant> Tenants = new List<Tenant>();
}
public class Tenant
{
public string Name { get; set; }
public int SF { get; set; }
public decimal Rent { get; set; }
}
How can I do this in Python? Actually I've been kind of confused in general how to 'declare' class member variables.. it seems like the closest thing to declaring them is setting them to a value for the first time in the __init__ constructor, which feels odd to me. Anyways I'm new to Python so maybe that's just how it's done.
I've read a little bit about how tuples and lists are used in Python, so I'm guessing the solution would have something to do with that, but I'm having trouble figuring it out.
Thanks any help is appreciated

Visual Studio 2013 Rdlc - how to display values from navigation properties

I'm bulding a WPF application on visual studio 2013 with Entity-Framework (Code First).
I have a Order class, that has a virtual property for Customer.
public class Order
{
public int OrderId { get; set; }
public DateTime OrderDate { get; set;}
public virtual Customer Customer { get; set; }
}
public class Customer
{
public int CustomerId { get; set; }
public string Name { get; set; }
public string DocumentNumber { get; set; }
public DateTime BirthDate { get; set; }
}
I'm trying to show the customer's name on report formula. I've tried:
=First(Fields!Customer.Value.Name, "MyDataSet")
=First(Fields!Customer.Name.Value, "MyDataSet")
and
=Fields!Customer.Value.Name
=Fields!Customer.Name.Value
It just shows #Error on that field. Other fields from Order are displayed properly.
It works:
=First(Fields!OrderDate.Value, "MyDataSet")
I loaded the Customer by using Include when I retrieve the entity from context. So a null reference is not the problem.
Order order = context.Orders.Include(o => o.Customer).Where(o => o.OrderID == id).FirstOrDefault();
I searched the following and others, but sounds like is just for visual studio 2010 or just didn't work:
Bind child object property with in rdlc (Report)
http://wraithnath.blogspot.com.br/2011/04/reportviewer-object-datasource-nested.html
Is there some thing I didn't do or I should work another way on that, like some kind of "code-first-view"?
This answer worked for me in VS2013:
http://wraithnath.blogspot.com/2011/04/reportviewer-object-datasource-nested.html
Be sure you classess fullfill with the requirements, remember add the parameterless constructor, (it only worked for me until i added the parameterless constructor)
Checklist:
ALL classes are serializable (every user type in the class must be
serializable, and any user type in a property of a usertype must be
serialzable)
ALL classes have a public parameterless constructor
ALLclasses used in the report must have the public modifier
If any property of the datasource, or any property of a property cannot be
serialized then your will get the #Error. Just make sure everything
is serializable
Make sure there will be no infinite recursion issues eg, class A has a
property of class B, and class B has a property of class A. Use XMLIgnore / ScriptIgnore attributes
This are my classes:
[Serializable]
public class Person
{
public Person()
{
}
public string Name{ get; set; }
public string Address1{ get; set; }
public string Id{ get; set; }
public string Phone { get; set; }
}
Parent:
[Serializable]
public class Header
{
public Header()
{
}
public string Product { get; set; }
public DateTime EmisionDate{ get; set; }
public string Number { get; set; }
public Person Person { get; set; }
}
And this is my expression
=First(Fields!Person.Value.Name, "dsHeader")
I'm not sure if this is the accepted standard for doing this kind of thing but what I've found to be the most reliable. (VS Rdlc work is bugged to hell and not well documented in the wpf realm)
So you have your dataset for your 'Order' object which contains the customer object you're trying to access properties from. Now, create another dataset of the 'Customer' object.
Then in code, populate your 'Order' object with everything as you normally would and then set the second dataset's binding source we created based on your 'Customer' object to the 'Customer' object that is inside your 'Order' object
Order order = new Order();
order.OrderId = 1;
order.OrderDate = DateTime.Now;
order.Customer = new Customer("John", "Shmoe");
OrderBindingDataSet.DataSource = order;
CustomerBindingDataSet.DataSource = order.Customer;
Hope this helps, I know from personal experience how irritating it is to have to use this piece of work along with it having little to no documentation for these kind of things. :)

Cannot access nested classes or members of base class

I'm having some weird problems here with a Class that I've written. I cannot access anything inside of Account, unless I access it directly from Account.Whatever.
I'd like to be able to do:
Account account = new Account();
account.Name...
but I can't. Nothing shows up in intellisense. I can only access things if I do:
Account. - for example, Account.AccountHolder...
class Account
{
class AccountHolder
{
enum Salutation
{
Mr,
Mrs,
Ms,
Miss,
Dr,
Hon
}
struct Name
{
public string FirstName { get; set; }
public string MiddleName { get; set; }
public string LastName { get; set; }
}
enum Sex
{
Male,
Female
}
}
}
I don't understand what's going on. Note, that I have also tried every possible combination of things but something is very wrong here. I've tried adding public to my Account class. I've tried adding public to my AccountHolder class. I've tried using public static etc etc etc.
I've never had this problem before. And why am I experiencing this same problem no matter how much I change it around?
The Account class is in an Account.cs file inside the same winforms project.
One real question might be: Why do you need Nested Types here at all?
Nested types are especially used when no other types cannot reuse a type of your parent type, that is, if your nested type shall expose properties or values only applicable to your parent type. Otherwise it is mostly best to create independant types.
To me, it looks reasonable to think that you might use the Salutation enumeration outside of the AccountHolder class, as an Account Holder is nothing more than a legal entity, that is, a real person or a company.
If your system could use Salutation elsewhere, than it is best to create the enumeration per itself, in its own file, and expose a property out of your AccountHolder class.
Salutation
public enum Salutation {
Mr
, Mrs
, Ms
, Miss
, Dr
, Hon
}
AccountHolder
public class AccountHolder {
public Salutation Salutation { get; set; }
// ...
}
In the later, one might also be insterested to know what's an account holder at once?
Might it be a company, a person, a customer, a supplier, or else?
Then perhaps shall you consider to define a hierarchy of account holders and make it a property of the most general class type.
LegalEntity
public class LegalEntity {
public string Name { get; set; }
}
Company
public class Company : LegalEntity {
// Some members specific to a Company here...
}
Person
public class Person : LegalEntity {
public Salutation Salutation { get; set; }
public string FirstName { get; set; }
public string MiddleName { get; set; }
public string LastName { get { return base.Name; } set { base.Name = value; } }
// Some other members specific to a person here...
}
Then, you have your Account class
public class Account {
public LegalEntity AccountHolder { get; set; }
}
So my point is that there is no use of Nested Types here, depending on your needs, which I'm not actually aware, obviously. And it turns out that an AccountHolder may now be of any types deriving from LegalEntity. Later on, when there is a need for another type of AccountHolder, you may simply derive from LegalEntity, or any other types which actually derives from it to make it an AccountHolder, as an AccountHolder is simply a property of an Account, and not a class per itself.
Some examples of using Nested Types adequately:
Why Would I Ever Need to Use C# Nested Classes
Why/when should you use nested classes in .net? Or shouldn't you?
Furthermore, you will need to make your Nested Types public in order to access them from outside of your class. This doesn't mean that will be able to avoid the Parent.NestedType nomenclature, you will not.
Apart from it, I see no problem in your code. Nested Types are by definition hidden somehow within another type. So when you wish to access them, you always need to type in the parent name which contains the type you need to access.
Plus, once you can access the Nested Type, you will be obliged to create members into your Account class to holde references to your instances of those Nested Types. IMHO, there is no gain of using them here. But hey, I insist, I'm not aware of your reality and the choices behind your design.
You are trying to access nested class, struct, enum. It should be done with the nesting class name, e.g. Account.Name.
But if you have
class Account
{
public struct Name
{
public string FirstName { get; set; }
public string MiddleName { get; set; }
public string LastName { get; set; }
}
public Name MyName {get; set;}
}
then you may access the MyName property using the instance of Account class.
This is how the language works.
What you are probably wanting to use here are namespaces. Any nested class will always have to be fully qualified with its parent classes to be used. If you use a namespace, anything within that namespace can be used together without fully-qualifying, and can be used outside the namespace (within the bounds of access modifiers) by either fully-qualifying or by inserting a using directive (using Accounting; in this case).
Also, are you sure you want to be using a struct? Value types are immutable, so if you change any member of that struct, you're always creating an entirely new instance of the struct (generally significantly less efficient).
namespace Accounting
{
class Account
{
public PersonName Name { get; set; }
public Sexes Sex { get; set; }
public Salutations Salutation { get; set; }
}
class PersonName
{
public string First { get;set; }
public string Middle { get; set; }
public string Last { get; set; }
}
enum Salutations : byte
{
Mr,
Mrs,
Ms,
Miss,
Dr,
Hon
}
enum Sexes : byte
{
Male,
Female
}
}

Categories

Resources