private DbExpression GetMemberExpressionByPath(TranslationContext context, DbUnitItemTypeExpression item, string path) { if (string.IsNullOrEmpty(path)) { throw new ArgumentNullException(Res.ExceptionMemberPathCannotEmpty, nameof(path)); } var paths = path.Split('.'); var metadata = context.Context.Configuration.Metadata; DbExpression current = null; NavigateMetadata navigate = null; for (var i = 0; i < paths.Length; i++) { var table = current == null?metadata.Table(item.ClrType) : navigate.Target; var navikeyvalue = table.Navigates.Where(a => a.Key.Name == paths[i]).FirstOrDefault(); var propertyinfo = navikeyvalue.Key as PropertyInfo; if (propertyinfo == null) { throw new KeyNotFoundException(Res.ExceptionNotFoundNavigateKey); } if (propertyinfo.PropertyType.IsComplexCollection() && i != paths.Length - 1) { throw new ArgumentException(Res.ExceptionCollectionMemberLevelError); } current = CreateMemberExpression(context, propertyinfo, current == null ? item : current); navigate = navikeyvalue.Value; } return(current); }
/// <summary> /// 初始化导航元数据及关系信息。 /// </summary> /// <param name="metadata">导航元数据。</param> /// <param name="parent">父级表达式。</param> private void InitialNavigate(NavigateMetadata metadata, DbExpression parent) { Metadata = metadata; TargetSet = new DbDataSetExpression(typeof(IEnumerable <>).MakeGenericType(metadata.Target.ClrType)); var comNavi = metadata as CompositeNavigateMetadata; if (comNavi != null) { RelationSet = new DbDataSetExpression(typeof(IEnumerable <>).MakeGenericType(comNavi.RelationTable.ClrType)); Pairs = comNavi.Pairs.Select(a => { var left = new DbMemberExpression(a.ForeignKey.Member, RelationSet); var right = new DbMemberExpression(a.PrincipalKey.Member, parent); return(new DbJoinKeyPairExpression(left, right)); }).ToArray(); CompositePairs = comNavi.CompositePairs.Select(a => { var left = new DbMemberExpression(a.PrincipalKey.Member, TargetSet); var right = new DbMemberExpression(a.ForeignKey.Member, RelationSet); return(new DbJoinKeyPairExpression(left, right)); }).ToArray(); } else { Pairs = metadata.Pairs.Select(a => { var left = new DbMemberExpression(a.ForeignKey.Member, parent); var right = new DbMemberExpression(a.PrincipalKey.Member, TargetSet); return(new DbJoinKeyPairExpression(left, right)); }).ToArray(); } Nullable = Metadata.Pairs.Select(a => a.ForeignKey.Member) .OfType <PropertyInfo>().All(a => a.PropertyType.IsNullable()); }
/// <summary> /// 创建关系操作基类。 /// </summary> /// <param name="context">数据上下文。</param> /// <param name="member">关系导航属性。</param> /// <param name="type">目标数据类型。</param> /// <param name="table">当前数据表元数据。</param> /// <param name="navigate">当前关系元数据。</param> internal DbRelationOperateBase(DbContext context, PropertyInfo member, Type type, TableMetadata table, NavigateMetadata navigate) : base(context, type, null) { Member = member; Table = table; Navigate = navigate; _ItemParameterCount = Navigate.Source.Keys.Length + Navigate.Target.Keys.Length; }
/// <summary> /// 添加关系操作。 /// </summary> /// <param name="context">数据上下文。</param> /// <param name="member">成员CLR描述对象。</param> /// <param name="type">相关源类型。</param> /// <param name="table">相关表元数据。</param> /// <param name="navigate">相关导航元数。</param> internal DbAddRelationOperate(DbContext context, PropertyInfo member, Type type, TableMetadata table, NavigateMetadata navigate) : base(context, member, type, table, navigate) { }