i'm have a hard and extreming question, how i'm may using FluentNHibernate for mapping a interface? follow a example below how i'm imagine do:
I'm have a interface:
public interface IUser
{
String Name { get; set; }
City City { get; set; }
}
and i'm have a class with implement this interface:
public class User : IUser
{
String Name { get; set; }
ICity City { get; set; }
}
Consider witch too exist a class for City and contains a property named Country and too exists at its interface...
I need to use FluentNHibernate to do the mapping as follows:
public class UserMap : ClassMap<IUser>
{
public UserMap()
{
Map(e => e.Name);
References<City>(x => x.City).Cascade.All();
}
}
public class CityMap: ClassMap<ICity>
{
public CityMap()
{
Map(e => e.Country);
}
}
It looks like mapping interfaces is supported:
It is perfectly acceptable for the named persistent class to be an interface. You would then declare implementing classes of that interface using the <subclass> element.
The <subclass> element's equivalent in Fluent NHibernate is SubclassMap<T>, I suppose. Therefore, although it's not clear what your actual problem is, can you try this instead:
public class UserMap : SubclassMap<IUser>
{
}
public class CityMap: SubclassMap<ICity>
{
}
Related
I have 3 classes with the name of Employee, EmployeeTwo, and EmployeeThree, I wanted to map Employee to EmployeeTwo and Employee to EmployeeThree.
Following are the Classes.
I also have tried to define the AdaptMember attribute on the Employee Class property but it only defines one and I have to map it with two different.
Note: I cannot define any attribute to the EmployeeTwo and EmployeeThree classes because this comes from the API and it can be regenrate.
public class Employee
{
[AdaptMember(nameof(EmployeeTwo.EmployeeID))]
public int ID { get; set; }
[AdaptMember(nameof(EmployeeTwo.EmployeeName))]
public string Name { get; set; }
}
public class EmployeeTwo
{
public int EmployeeID { get; set; }
public string EmployeeName { get; set; }
}
public class EmployeeThree
{
public int EmployeeThreeID { get; set; }
public string EmployeeThreeName { get; set; }
}
Any help is really appriciated.
As I understand you, you want to make a custom object mapping using mapster.
If you want to make a custom mapping you need to create a class:
using Mapster;
namespace Application.Mapsters
{
public class Config : ICodeGenerationRegister
{
public void Register(CodeGenerationConfig config)
{
TypeAdapterConfig<Employee, EmployeeTwo>
.NewConfig()
.Map(dst => dst.EmployeeID, src => src.ID)
.Map(dst => dst.EmployeeName, src => src.Name);
}
}
}
For instance, follow this example to see how to make a custom mapping using mapster:
https://floatincode.net/2021/07/26/mapster-generate-dto-async-after-map-actions-dependency-injection/
In my ASP.NET Core API, I have a DTO class BaseBDto and another DerivedBDto that inherits from it, and hides some of its properties, because they're required in DerivedBDto. The properties of BaseBDto and DerivedBDto are objects of another classes, BaseADto and DerivedADto respectively, that follow the same logic as the first ones. I also have a BaseModel class to which both BaseBDto and DerivedBDto will be mapped through another class Mapper.
Something like the following code:
using System.ComponentModel.DataAnnotations;
public class BaseADto
{
public string Name { get; set; }
}
public class DerivedADto : BaseADto
{
[Required]
public new string Name { get; set; }
}
public class BaseBDto
{
public BaseADto A { get; set; }
}
public class DerivedBDto : BaseBDto
{
[Required]
public new DerivedADto A { get; set; }
}
public class BaseModel
{
public string NameModel { get; set; }
}
public static class Mapper
{
public static BaseModel MapToModel(BaseBDto dto) => new BaseModel
{
NameModel = dto.A.Name
};
}
But it turns out, when passing a DerivedBDto object to the MapToModel method, it's trying to access the values of the BaseBDto (which are null) instead of the DerivedBDto ones.
Is there any way I can achieve this behavior?
I can only think of declaring BaseBDto as abstract, but that would prevent me from instantiating it, which I need to do.
PS: I already asked a similar question here, but I oversimplified my code sample, so I felt another question was necessary.
Also, the solution provided there doesn't work because I can't override the A property at DerivedBDto with a DerivedADto since it must have the same type as the A property at BaseBDto.
Have you tried changing the MapToModel signature to be generic. The below
public static BaseModel MapToModel<T>(T dto) where T : BaseBDto => new BaseModel
{
NameModel = dto.A.Name
};
It is clearly explained here how to achieve "multiple inheritance" in C# by using Interface. However, I wonder, how to achieve the same but in the Entity Framework Code First Workflow.
Provided code to make things clear :
public abstract class DomainObject {
// Every business model must have this fields
public Guid Id {get;set;}
public string SystemCode {get;set;}
}
And here also some optional abstract classes like:
public abstract class MultiTitleObject : DomainObject {
public string TitleRu { get; set; }
public string TitleEn { get; set; }
}
public abstract class ManageableByAdminObject : DomainObject {
public bool isVisibleOnSite {get;set;}
public bool isDeletedByAdmin {get;set;}
}
Let's say that I have class that need to have fields of both MultiTitleObject and ManageableByAdminObject and DomainObject as always rule.
Since C# doesn't support multiple inheritance, I can do the following :
public class ManageableByAdminDomainObject : ManageableByAdminObject {
}
public class ManageableByAdminMultiTitleDomainObject : ManageableByAdminDomainObject {
// Even here it's too complicated...
// What if I need to inherit from 3 or more classes?
}
So the solution I wanted to use is Interface like :
public interface IFieldImitation {
bool isVisibleOnSite ();
}
public class ManageableByAdminObject : IFieldImitation, DomainObject {
public bool isVisibleOnSite () => return true;
}
However, EF does understand abstract classes but not the interfaces.
How should I solve this problem?
I've got a base class MyBase which is a part of my data model. I also have classes MyChild1, MyChild2 derived from it in related assemblies.
I want the children to be stored in database and loaded just like MyBase. Also I don't want my entity configuration to know anything about children classes.
Is there any way to force EF to ignore that inheritance and user only base class?
Thanks in advance
Here is your case:
public abstract class BaseModel
{
public int Id { get; set; }
public string Name { get; set; }
}
public partial class Child1 : BaseModel
{
public string Name1 { get; set; }
}
public partial class Child2 : BaseModel
{
public string Name2 { get; set; }
}
I guess your data should be similar like this (I am not sure your detail requirements, here is just an example):
public partial class Example<T> where T: BaseModel
{
public int Id { get; set; }
public T Data { get; set; } // so here could be any Child of BaseModel
}
public partial class Example: Example<BaseModel>
{
}
Use ModelBuilder.Ignore<>() Method to let EFCore ignore your children and base.
User PropertyBuilder.HasConversion Method to convert your data to/from database.
Here is sample code:
public class MyDbContext : DbContext
{
public virtual DbSet<Example> Examples { get; set; }
protected override void OnModelCreating(ModelBuilder builder)
{
//Let EFCore ignore all models that you don't want it to be a table
builder.Ignore<BaseModel>();
builder.Ignore<Child1>();
builder.Ignore<Child2>();
builder.Entity<Example>(entity =>
{
entity.Property(p => p.Data).HasConversion(
x => JsonConvert.SerializeObject(x) //convert TO a json string
, x => JsonConvert.DeserializeObject<BaseModel>(x)//convert FROM a json string
);
});
}
}
Let's use a quite plain example with employees and company(-ies).
public abstract class Employee
{
// bunch of its features
}
public sealed class SalesManager : Employee
{
}
public sealed class SEO : Employee
{
}
Employee can take different posts or play different roles. So using inheritance (maybe with factory patterns in addition) doesn't give such a flexibility for concrete employee instance to change its role.
What would you advice, unfortunately I haven't seen the kind of approaches yet. And I haven't met a book which lights up the problem.
Edit
Thank you guys! In my edit I wanted to ask one more thing. Using generic role is it possible to transfer such a BLL to DAL. I have heard that generics are not supported in Entity Framework??
Thanks!
Use a has-a relationship
public class Employee
{
public Role EmployeeRole { get; set; }
}
public enum Role
{
SalesManager,
SalesPerson
}
Or you can make Role a class to store additional information in addition to the name of their role.
public class Role
{
public string Name { get; set; }
public decimal BaseSalary { get; set; }
}
To illustrate #Aasmund Eldhuset's comment:
public abstract class Role
{
public string Name { get; set; }
public decimal BaseSalary { get; set; }
public abstract void PerformRole();
}
public class SalesPerson : Role
{
public void PerformRole()
{
// Do something
}
}
Running with the idea of using a class, you can make it generic:
abstract class EmployeeRole { }
or
interface EmployeeRole { }
And have different types inherit from this abstraction:
class CEO : EmployeeRole { }
class SalesMgr : EmployeeRole { }
class Employee<T> where T : EmployeeRole
{
}
Then have a generic Factory implementation:
public Employee<T> MakeEmployee<T>() where T : EmployeeRole
{
}