EF code first and two way relationships - entity-framework

this.HasRequired(t => t.Parent)
.WithMany(t => t.Children)
.HasForeignKey(d => d.ParentId);
Here I defined a basic 1-to-many relationship. What if I do not want to have Children property exposed at all in Model, but still want to have synchronization of values between Parent and ParentId. How would I go defining such "relationship"?

You will call WithMany without any parameter:
this.HasRequired(t => t.Parent)
.WithMany()
.HasForeignKey(d => d.ParentId);

Related

Is there any way to create EF mapping classes using Visual Studio or other tools from a SQLite Database?

Here is one that I created for a SQL Server a while ago. But I need similar for a new SQLite Database now.
public TopicMap()
{
// Primary Key
this.HasKey(t => t.TopicId);
// Identity
this.Property(t => t.TopicId)
.HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
// Properties
this.Property(t => t.Name)
.IsRequired()
.HasMaxLength(255);
this.Property(t => t.Number)
.IsRequired();
this.Property(t => t.Version)
.IsRequired()
.IsFixedLength()
.HasMaxLength(8)
.IsRowVersion();
// Table & Column Mappings
this.ToTable("Topic");
this.Property(t => t.TopicId).HasColumnName("TopicId");
this.Property(t => t.Number).HasColumnName("Number");
this.Property(t => t.Name).HasColumnName("Name");
this.Property(t => t.SubjectId).HasColumnName("SubjectId");
this.Property(t => t.Version).HasColumnName("Version");
this.Property(t => t.CreatedBy).HasColumnName("CreatedBy");
this.Property(t => t.CreatedDate).HasColumnName("CreatedDate");
this.Property(t => t.ModifiedBy).HasColumnName("ModifiedBy");
this.Property(t => t.ModifiedDate).HasColumnName("ModifiedDate");
this.Property(t => t.Created).HasColumnName("Created");
this.Property(t => t.Modified).HasColumnName("Modified");
// Relationships
this.HasRequired(t => t.Subject)
.WithMany(t => t.Topics)
.HasForeignKey(d => d.SubjectId)
.WillCascadeOnDelete(false);
}
I now have a complex SQLite Database but cannot find any tools at all that will work to create the model and mapping classes automatically.
Does anyone know of anything that exists?
With EF Core, you can use EF Core Power Tools. You must install the SQLite Visual Studio Tools.
More info here: https://github.com/ErikEJ/EFCorePowerTools/wiki/Reverse-Engineering

Using Mapster to map from flat model to a model with nested properties in TypeAdapterConfig

Using EF Core 3 and Mapster I would like to map from a flat dto object to an object with a related sub-object.
i.e.
_ = TypeAdapterConfig<NoteVM, Note>.NewConfig()
.Map(d => d.Detail, s => s.Description)
.Map(d => d.Id, s => s.NoteId)
.Map(d => d.NoteTypeObject, s => s.NoteTypeString)
.IgnoreNullValues(true);
Where NoteTypeObject is an existing record on a table.
So in the mapping the NoteType object has to be retrieved from the db and attached to the Note record before the Note record is saved.
Can this be done in the config section or does this need to be done after the mapping but before the Note object is saved to the DB?
_ = TypeAdapterConfig<NoteVM, Note>.NewConfig()
.Map(d => d.Detail, s => s.Description)
.Map(d => d.Id, s => s.NoteId)
//get existing Id
.Map(d => d.NoteTypeObjectId, s => GetNoteTypeId(s.NoteTypeString))//lookup
.IgnoreNullValues(true);
If you are able to add a reference ID instead of object reference you can do something like the above.

Automapper: mapping properties outside source entity

I have a legacy ASP.NET Web forms application which uses ASP.NET GridView.
There's [User] class, which represents an entity from EF model, and then there's [UserDto]. All properties in the UserDto maps to the User class, except for one - which is RowCount. This is actually not a property related to the user itself, but in a legacy implementation, we have the total rowcount attached to each User object in the User list to show the correct page number in the Gridview.
So here's how my mapping goes:
config.CreateMap<User, UserDto>()
.ForMember(dest => dest.Id, opt => opt.MapFrom(u => u.UserId))
.ForMember(dest => dest.Username, opt => opt.MapFrom(u => u.UserName))
.ForMember(dest => dest.Usercode, opt => opt.MapFrom(u => u.UserCode))
.ForMember(dest => dest.FirstName, opt => opt.MapFrom(u => u.FirstName))
.ForMember(dest => dest.LastName, opt => opt.MapFrom(u => u.LastName))
.ForMember(dest => dest.Branch, opt => opt.MapFrom(u => u.Branch))
.ForMember(dest => dest.Groups, opt => opt.MapFrom(u => u.UserGroups))
.ForMember(dest => dest.AssignedUsers, opt => opt.MapFrom(u => u.User12.Select(s => s.FirstName + " " + s.LastName)));
Then I retrieve the users and map it to the DTO as follows:
var users = (from u in context.Users.Include("Branch")
where (u.FkBranchId == branchId || branchId == -1)
select u).ToList();
// get the total row count to support paging
var rowCount = users.Count;
var orderedList = CustomSort.GetSortedList(users, sortInfo.SortColumn, sortInfo.SortDirection).Skip(pageInfo.Skip).Take(pageInfo.PageSize).ToList();
return mapper.Map<List<EFModel.ClientData.User>, List<UserDto>>(orderedList);
Here I'm thrown an error, obviously, because the RowCount property in my DTO is not mapped. Notice that I want to map it to a property outside of the user object, i.e. the list count.
How do I do this?

Mongoid syntax for querying based on several sets of attributes

Assuming I want to get 3 documents which fit one of these attributes
Class Question:
name=>a, topic=>b
name=>c, topic=>d
name=>e, topic=>f
What is the appropriate syntax for mongoid to get these?
According to mongoid query syntax:
Model.any_of({:name => a, :topic => b},
{:name => c, :topic => d},
{:name => e, :topic => f})

MooseX::Types coercions and $self

Is there anyway to get $self into a MooseX::Types coercion? I have other data in the object that I want to use to seed my coercion from a String to an Object. Alternatively, is there anything like Class::MOP's initializer that will permit me to do this -- it would have to fire before the type checks.
Requested pseudo code:
with 'DBHandle';
has 'database' => ( isa => 'Str', is => 'ro', default => 'Db' );
has 'schema' => ( isa => 'Str', is => 'ro', default => 'schema' );
has 'table' => ( isa => 'Str', is => 'ro', default => 'column );
has 'columns' => ( isa => DBCols, is => 'ro', default => sub {[qw/foo bar baz/]} );
Here, I want "columns" to coerce to a DBCols -- an ArrayRef of DBCol's (objects) -- requiring the use of catalog, schema, and col attributes found in the class, and with a dbh/singleton provided by DBHandle.
To make this less-pseudo, the actually situation is only slightly more complex. I was able to accomplish the above with around, now what I want I to do is create an attribute trait that would permit this syntax:
has 'column_id' => (
isa => Int
, is => 'ro'
, traits => ['DBKey']
, default => 5
, column => 'foo'
);
Where the attribute trait column provided by DBKey, coerces to DBCol the same way that the above columns would: this would require the ability to access the classes database, schema, table, and again the singleton for the dbh.
No. It'd be nice, but coercions are really designed to be global, and no one has written a "context-sensitive coercion" yet, because no one's really sure how to. (Actually, s/coercions/type constraints/ -- it'd be useful just to say "this Str must be a valid column name, defined as an entry in this object's columns HashRef".)
People usually solve this problem with around and/or some combination of BUILD and BUILDARGS.