-
Notifications
You must be signed in to change notification settings - Fork 32
/
OeEdmModelMetadataProvider.cs
111 lines (104 loc) · 5.1 KB
/
OeEdmModelMetadataProvider.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
using OdataToEntity.Parsers;
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Reflection;
namespace OdataToEntity.ModelBuilder
{
public class OeEdmModelMetadataProvider
{
public virtual PropertyInfo[]? GetForeignKey(PropertyInfo propertyInfo)
{
var fkey = (ForeignKeyAttribute?)propertyInfo.GetCustomAttribute(typeof(ForeignKeyAttribute));
if (fkey == null)
return null;
PropertyInfo? property = propertyInfo.DeclaringType!.GetPropertyIgnoreCaseOrNull(fkey.Name);
if (property == null)
{
String[] propertyNames = fkey.Name.Split(',');
if (propertyNames.Length == 1)
throw new InvalidOperationException("property " + fkey.Name + " foreign key " + propertyInfo.Name + " not found");
var properties = new PropertyInfo[propertyNames.Length];
for (int i = 0; i < properties.Length; i++)
{
String propertyName = propertyNames[i].Trim();
property = propertyInfo.DeclaringType!.GetPropertyIgnoreCase(propertyName) ??
throw new InvalidOperationException("property " + propertyName + " foreign key " + propertyInfo.Name + " not found");
properties[i] = property;
}
return properties;
}
return new PropertyInfo[] { property };
}
public virtual PropertyInfo? GetInverseProperty(PropertyInfo propertyInfo)
{
var inverse = (InversePropertyAttribute?)propertyInfo.GetCustomAttribute(typeof(InversePropertyAttribute));
if (inverse == null)
return null;
Type clrType = OeExpressionHelper.GetCollectionItemTypeOrNull(propertyInfo.PropertyType) ?? propertyInfo.PropertyType;
return clrType.GetPropertyIgnoreCase(inverse.Property);
}
public virtual IReadOnlyList<PropertyInfo> GetManyToManyProperties(Type clrType)
{
List<PropertyInfo>? properties = null;
foreach (PropertyInfo propertyInfo in clrType.GetProperties())
if (IsNotMapped(propertyInfo) &&
!OeExpressionHelper.IsPrimitiveType(propertyInfo.PropertyType) &&
OeExpressionHelper.GetCollectionItemTypeOrNull(propertyInfo.PropertyType) != null)
{
if (properties == null)
properties = new List<PropertyInfo>();
properties.Add(propertyInfo);
}
return properties ?? (IReadOnlyList<PropertyInfo>)Array.Empty<PropertyInfo>();
}
public virtual int GetOrder(PropertyInfo propertyInfo)
{
ColumnAttribute? column = propertyInfo.GetCustomAttribute<ColumnAttribute>();
return column == null ? -1 : column.Order;
}
public virtual PropertyInfo[]? GetPrincipalStructuralProperties(PropertyInfo principalNavigation)
{
return null;
}
public virtual PropertyInfo[] GetPrincipalToDependentWithoutDependent(PropertyInfo principalNavigation)
{
Type? itemType = OeExpressionHelper.GetCollectionItemTypeOrNull(principalNavigation.PropertyType);
if (itemType != null && GetInverseProperty(principalNavigation) == null)
{
String dependentPropertyName = principalNavigation.DeclaringType!.Name + "id";
return new PropertyInfo[] { itemType.GetPropertyIgnoreCase(dependentPropertyName) };
}
throw new InvalidOperationException("Pricipal structurlal property not found for principal navigation " + principalNavigation.Name);
}
public virtual PropertyInfo[] GetProperties(Type type)
{
return type.GetProperties(BindingFlags.Instance | BindingFlags.Public | BindingFlags.DeclaredOnly);
}
public virtual bool IsDatabaseGenerated(PropertyInfo propertyInfo)
{
DatabaseGeneratedAttribute? attribute = propertyInfo.GetCustomAttribute<DatabaseGeneratedAttribute>();
return attribute != null && attribute.DatabaseGeneratedOption != DatabaseGeneratedOption.None;
}
public virtual bool IsKey(PropertyInfo propertyInfo)
{
return propertyInfo.IsDefined(typeof(KeyAttribute));
}
public virtual bool IsNotMapped(PropertyInfo propertyInfo)
{
return propertyInfo.IsDefined(typeof(NotMappedAttribute));
}
public virtual bool IsRequired(PropertyInfo propertyInfo)
{
return !PrimitiveTypeHelper.IsNullable(propertyInfo.PropertyType) ||
propertyInfo.IsDefined(typeof(RequiredAttribute)) ||
IsKey(propertyInfo);
}
public void SortClrPropertyByOrder(PropertyInfo[] clrProperties)
{
if (clrProperties.Length > 1)
Array.Sort(clrProperties, (x, y) => GetOrder(x).CompareTo(GetOrder(y)));
}
}
}