Skip to content

Instantly share code, notes, and snippets.

@habib-sadullaev
Created September 16, 2021 16:24
Show Gist options
  • Select an option

  • Save habib-sadullaev/d65a24cd634b8bf0c55b17101872c9d4 to your computer and use it in GitHub Desktop.

Select an option

Save habib-sadullaev/d65a24cd634b8bf0c55b17101872c9d4 to your computer and use it in GitHub Desktop.

Revisions

  1. habib-sadullaev created this gist Sep 16, 2021.
    84 changes: 84 additions & 0 deletions code-first Splitting table fix
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,84 @@
    namespace Data.Model.Entities
    {
    using System;
    using System.Data.Entity.Core.Metadata.Edm;
    using System.Data.Entity.Infrastructure;
    using System.Data.Entity.ModelConfiguration.Conventions;
    using System.Linq;
    using System.Reflection;

    public class CommentSplittingFixer : IStoreModelConvention<EdmModel>
    {
    private static readonly PropertyInfo[] splittedProps =
    (from p in typeof(Comment).GetProperties()
    where typeof(BaseEntity).IsAssignableFrom(p.PropertyType)
    where p.PropertyType != typeof(User)
    where p.PropertyType != typeof(Comment)
    select p).ToArray();

    private static readonly string[] splittedPropNames =
    splittedProps.Select(p => p.Name).ToArray();

    public virtual void Apply(EdmModel item, DbModel model)
    {
    FixConceptualModel(model);
    FixStoreModel(model);
    FixConceptualToStoreMapping(model);
    }

    private static void FixConceptualModel(DbModel model)
    {
    var navs = from e in model.ConceptualModel.EntityTypes
    where e.Name == nameof(tcComment)
    from nav in e.NavigationProperties
    where splittedPropNames.Contains(nav.Name)
    select nav;
    foreach (var nav in navs)
    {
    nav.FromEndMember.Name = (nav.FromEndMember.TypeUsage.EdmType as RefType).ElementType.Name;
    nav.ToEndMember.Name = (nav.ToEndMember.TypeUsage.EdmType as RefType).ElementType.Name;
    };
    }

    private static void FixStoreModel(DbModel model)
    {
    var endMembers = from assoc in model.StoreModel.AssociationTypes
    from AssociationEndMember m in assoc.Members
    select m;
    foreach (var endMember in endMembers)
    endMember.DeleteBehavior = OperationAction.Cascade;

    foreach (var nav in splittedProps)
    {
    var entityType = nav.PropertyType;
    var isKey = new KeyConvention(entityType).IsKey;
    var foreignKey = (from e in model.StoreModel.EntityTypes
    where e.Name.StartsWith(nameof(Comment))
    from p in e.Properties
    where isKey(p.Name)
    select p).Single();
    foreignKey.Nullable = false;

    var assoc = (from e in model.StoreModel.AssociationTypes
    where e.Name.StartsWith(nameof(Comment))
    from AssociationEndMember m in e.Members
    where m.Name == entityType.Name
    select m).Single();
    assoc.DeleteBehavior = OperationAction.Cascade;
    assoc.RelationshipMultiplicity = RelationshipMultiplicity.One;
    }
    }

    private static void FixConceptualToStoreMapping(DbModel model)
    {
    var entityType = (from e in model.ConceptualToStoreMapping.EntitySetMappings
    where e.EntitySet.ElementType.Name == nameof(Comment)
    from m in e.EntityTypeMappings
    select m).Single();
    foreach (var fragment in entityType.Fragments.Where(f => f.StoreEntitySet.Name != nameof(Comment)).ToArray())
    {
    entityType.RemoveFragment(fragment);
    }
    }
    }
    }