Entity Framework and implementation of IPrincipal/IIdentity - entity-framework

As far as I am aware, for the property to be saved in the database it cannot be ReadOnly.
IIdentity properties: AuthenticationType, IsAuthenticated and Name are all ReadOnly.
Is making the wrapper to the properties that need to be saved the only solution or there are better ones?
EDIT:
I might not have explained my question that well. Here is the sample code for one of the ReadOnly properties, I have added UserName property for the Entity Framework:
Public Property UserName As String
Get
Return _userName
End Get
Private Set(value As String)
userName = value
End Set
Public ReadOnly Property Name As String Implements System.Security.Principal.IIdentity.Name
Get
Return UserName
End Get
End Property
What I wanted to ask is if there is any better way of doing it.

IIdentity properties are read only but the implementation can have setters. If you are using EDMX for mapping you don't have to expose these setters as public.
Edit:
This is possible in C# so hopefully you can use similar approach with VB.NET (I can only read VB code, not write):
public interface ITest {
string Name { get; }
}
public class Test : ITest {
public string Name { get; set; }
}
The class offers setter even the interface didn't define it.

The EF persists objects, not interfaces. Your object can have whatever properties you would like it to have. You cannot add an interface to your entity model, but you can add an object type which implements that interface.

Related

How to query using fields of subclasses for Spring data repository

Here is my entity class:
public class User {
#Id
UserIdentifier userIdentifier;
String name;
}
public class UserIdentifier {
String ssn;
String id;
}
Here is what I am trying to do:
public interface UserRepository extends MongoRepository<User, UserIdentifier>
{
User findBySsn(String ssn);
}
I get an exception message (runtime) saying:
No property ssn found on User!
How can I implement/declare such a query?
According to Spring Data Repositories reference:
Property expressions can refer only to a direct property of the managed entity, as shown in the preceding example. At query creation time you already make sure that the parsed property is a property of the managed domain class. However, you can also define constraints by traversing nested properties.
So, instead of
User findBySsn(String ssn);
the following worked (in my example):
User findByUserIdentifierSsn(String ssn);

The type 'Company.Model.User' and the type 'Company.Core.Model.User' both have the same simple name of 'User' and so cannot be used in the same model

I have a base entity class MyCompany.Core.Model.User which is to be used for common properties of a User entity:
public class User
{
public string Username { get; set; }
public string Usercode { get; set; }
}
I also have a base mapping class MyCompany.Core.Model.UserMap to setup the code first mappings for the base User class:
public class UserMap<TUser> : EntityMapBase<TUser>
where TUser : User
{
public UserMap()
{
// Primary Key
this.HasKey(t => t.Usercode);
// Table & Column Mappings
this.ToTable("Users");
this.Property(t => t.Username).HasColumnName("Username");
this.Property(t => t.Usercode).HasColumnName("UserCode");
}
}
In a separate assembly I have a derived class MyCompany.Model.User that inherits from the base User class and extends it with some additional properties:
public class User : Core.User
{
public string Surname { get; set; }
}
In addition I have a derived mapping class MyCompany.Model.UserMap to provide the additional configuration for the additional properties:
public class UserMap : Core.UserMap<User>
{
public UserMap()
{
this.Property(t => t.Surname).HasColumnName("Surname");
}
}
However when adding MyCompany.Model.User to the context and registering the MyCompany.Model.UserMap I'm getting the following error:
The type 'MyCompany.Model.User' and the type 'MyCompany.Core.Model.User' both have the same simple name of 'User' and so cannot be used in the same model. All types in a given model must have unique simple names. Use 'NotMappedAttribute' or call Ignore in the Code First fluent API to explicitly exclude a property or type from the model.
This link indicates that you can't have the same "simple name" in the model twice.
Why is the base class "simple name" being registered in the model, and is there a way around it in order to implement this sort of entity inheritance?
I suspect the simple solution would be to rename the derived class; however I would prefer to avoid this as there may be many derivations in multiple contexts.
Note: Using Entity Framework 6.0.0-rc1 (prerelease)
This is a limitation of EF that I reported in 2012 https://entityframework.codeplex.com/workitem/483 that is still not implemented in 6.0.2. EF uses a flat internal architecture and does not recognize namespaces. Might be coming in EF7 but not before. For now the only solutions is to rename the two classes to unique class names irrespective of the namespace they are in. IMHO, this is an significant limitation within EF. Just consider a class named Category and how many different namespaces it could be used within across a domain.
First read Table type mappings
The hierarchical implementation model options need to be understood first.
Then look at the IGNORE option. You may or may not need depending on chosen approach.
requires ignore ???
modelBuilder.Ignore<BaseXYZ>()
Ef is currently trying to include your base class to support an included Type that inherits from a NON abstract class.
This happens also if you forget to explicitly add a namespace in your class. Running on EF 6.4.4 and i can differentiate through namespaces.
e.g.
public class MyClass {}
Instead of:
namespace somenamespace
{
public class MyClass {}
}
To keep same class name I suggest to use different interfaces. An interface for the Core.Entity defining the common properties and an other interface for the extra properties. So instead of using a derived class you use a class implementing the two interfaces.
if you have 2 or more classes with a relationship between them like this:
public class A{
public X attribute1 {get;set;}
public B b {get;set;}
}
public class B{
public X attribute1 {get;set;}
}
sometimes in this situation it raises this error,
Solution :
change X name in one class.

Best practice for setting default values for model properties in Domain Driven Design?

What's the best way to set default properties for new entities in DDD? Also, what's the best way to set default states for complex properties (eg. collections)?
My feeling is that default values should be in the models themselves as they are a form of business rule ("by default, we want X's to be Y & Z"), and the domain represents the business. With this approach, maybe a static "GetNew()" method on the model itself would work:
public class Person {
public string Name { get; set; }
public DateTime DateOfBirth { get; set; }
public bool IsAlive { get; set; }
public List Limbs { get; set; }
public static Person GetNew() {
return new Person() {
IsAlive = true,
Limbs = new List() { RightArm, LeftArm, RightLeg, LeftLeg }
}
}
}
Unfortunately in our case, we need the collection property to be set to all members of another list, and as this model is decoupled from its Repository/DbContext it doesn't have any way of loading them all.
Crappy solution would be to pass as parameter :
public static Person GetNew(List<Limb> allLimbs) {
return new Person() {
IsAlive = true,
Limbs = allLimbs
}
}
Alternatively is there some better way of setting default values for simple & complex model properties?
This is an instance of the factory pattern in DDD. It can either be a dedicated class, such as PersonFactory, or a static method, as in your example. I prefer the static method because I see no need to create a whole new class.
As far as initializing the collection, the GetNew method with the collection as a parameter is something I would go with. It states an important constraint - to create a new person entity you need that collection. The collection instance would be provided by an application service hosting the specific use case where it is needed. More generally, default values could be stored in the database, in which case the application service would call out to a repository to obtain the required values.
Take a look at the Static Builder in Joshua Bloch's Effective Java (Second Edition). In there, you have a static builder class and you chain calls to set properties before construction so it solves the problem of either having a constructor that takes a ton of arguments or having to put setters on every property (in which case, you effectively have a Struct).

Order of mapping properties when loading from database

Let's say I have this code:
public bool Important { get; set; }
private bool _dependsOnImportant;
public bool DependsOnImportant
{
get;
set
{
if (value && !Important)
throw new InvalidOperationException();
_dependsOnImportant = value;
}
}
I want to protect setting DependsOnImportant to true, so that it is only possible when Important is true. This is POCO class. According to: Entity Framework 4.1 - Code first. Doesn't EF override my virtual members? my setter will be used by EF when loading object from database.
How can I be sure that Important has already been set with data from database when DependsOnImportant setter is called? Will EF be smart enough to detect that one setter is using another and load that data first? I don't think so. I think a new object is created with default constructor (setting all fields to default values) and then setters are invoked to populate the object.
So my questions are: Can we determine the order in which setters are called? But most importantly: Do we want to have that knowledge?

Adding custom property to object returned from WCF RIA Services

I have a stored procedure in my Entity Framework Model. I've added a Function Import and mapped the results to a Complex Type.
I want to add an extra property to this Complex type, that I'll populate in my Domain Service, not coming back from the stored procedure. I added a myClass.shared.cs file and implemented added the property like so:
//myClass.shared.cs
public partial class myClass
{
public string myProperty {get;set;}
}
I populate this in my domain service when I return the object, e.g.:
public myClass GetMyClass(int myClassID)
{
myClass theClass= this.ObjectContext.StoredProc(myClassID).FirstOrDefault();
class.myProperty = 12345;
return theClass;
}
When I get the return values of this method on the client side theClass.myProperty is always null but all values from the stored procedure are populated, am I missing something?
I've tried decorating the myProperty with the [DataMember] attribute but this throws the error:
"The type 'myClass' already contains a
definition for 'myProperty'"
How can I get this to return the value set in the Domain Service to the client?
There was no need to put this in the shared.cs class. The shared.cs class copies the actual code over to the client side and is useful for adding methods etc. but to add a new property, all I had to do was add a partial class (NOT in myClass.shared.cs) and decorate it with DataMember.
public partial class myClass
{
[DataMember]
public string myProperty {get;set;}
}