当我将注释链接到特定实体时,而不是创建这样的关系:
var associateRequest = new AssociateRequest
{
Target = new EntityReference(SalesOrder.EntityLogicalName, salesOrderGuid),
RelatedEntities = new EntityReferenceCollection
{
new EntityReference(Annotation.EntityLogicalName, noteGuid),
},
Relationship = new Relationship("SalesOrder_Annotation")
};
是否可以强类型方式引用该关系:
var associateRequest = new AssociateRequest
{
Target = new EntityReference(SalesOrder.EntityLogicalName, salesOrderGuid),
RelatedEntities = new EntityReferenceCollection
{
new EntityReference(Annotation.EntityLogicalName, noteGuid)
},
Relationship = SalesOrder.Relationships.SalesOrder_Annotation // <----- ???
};
这类似于能够在开发时获取逻辑名:
SalesOrder.EntityLogicalName
我们可以用同样的方式引用特定的1:N关系:
SalesOrder.Relationships.SalesOrder_Annotation
答案 0 :(得分:6)
如果您使用SDK(tf.diag_...
)中提供的标准RelationshipSchemaNameAttribute
应用程序生成代码,则您要查找的值将存储在代码属性CrmSvcUtil.exe
中。我已经使用SDK(\SDK\Bin\CrmSvcUtil.exe
)中提供的早期绑定实体类文件在控制台应用程序中验证了此代码。
按如下方式调用方法(根据您的示例):
\SDK\SampleCode\CS\HelperCode\MyOrganizationCrmSdkTypes.cs
或者,如果要返回实际的字符串值:
var relationship = GetRelationship<SalesOrder>(nameof(SalesOrder.SalesOrder_Annotation))
将此代码添加到应用程序中的帮助程序类:
var relationshipName = GetRelationshipSchemaName<SalesOrder>(nameof(SalesOrder.SalesOrder_Annotation))
这是您更新后的代码:
public static string GetRelationshipSchemaName<T>(string relationshipPropertyName) where T:Entity
{
return typeof (T).GetProperties()
.FirstOrDefault(x => x.Name == relationshipPropertyName)
.GetCustomAttributes()
.OfType<RelationshipSchemaNameAttribute>()
.FirstOrDefault()
?.SchemaName;
}
public static Relationship GetRelationship<T>(string relationshipPropertyName) where T : Entity
{
return new Relationship(typeof(T).GetProperties()
.FirstOrDefault(x => x.Name == relationshipPropertyName)
.GetCustomAttributes()
.OfType<RelationshipSchemaNameAttribute>()
.FirstOrDefault()
?.SchemaName);
}
答案 1 :(得分:5)
第二个想法,我的t4模板答案似乎有点矫枉过正 您可以使用表达式树和扩展方法轻松获得所需内容
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
namespace ConsoleApplication9
{
internal class Program
{
private static void Main(string[] args)
{
Relationship r = new Class1().GetRelationShip(s => s.RelationShipProperty);
Console.WriteLine(r.Name);
System.Console.ReadLine();
}
}
public static class MyExtention
{
public static Relationship GetRelationShip<T, TProperty>(this T t, Expression<Func<T, TProperty>> expression)
{
return new Relationship(((expression.Body as MemberExpression).Member as PropertyInfo)
.GetCustomAttributes(typeof(RelationshipAttribute))
.Select(a=>(RelationshipAttribute)a)
.First().Name
);
}
}
public class RelationshipAttribute : System.Attribute
{
public string Name { get; set; }
public RelationshipAttribute(string name)
{
Name = name;
}
}
public class Relationship
{
public string Name { get; set; }
public Relationship(string name)
{
Name = name;
}
}
public class Class1
{
[Relationship("RelationShipA")]
public List<int> RelationShipProperty { get; set; }
}
}
答案 2 :(得分:4)
根据您的说法,您生成的类具有一个属性,其中包含您的关系名称 您只需要一个t4模板,它可以为您的Relationships
生成一个具有强类型属性的类假设您的项目中包含以下代码
namespace ConsoleApplication9
{
public class RelationshipAttribute : System.Attribute
{
public string Name { get; set; }
public RelationshipAttribute(string name) { Name = name; }
}
[Relationship("RelationShipA")]
public class Class1 { }
[Relationship("RelationShipB")]
public class Class2 { }
[Relationship("RelationShipC")]
public class Class3 { }
}
此模板
<#@ template debug="false" hostspecific="false" language="C#" #>
<#@ assembly name="System" #>
<#@ assembly name="System.Core" #>
<#@ assembly name="$(TargetPath)" #>
<#@ import namespace="System.Collections.Generic" #>
<#@ import namespace="System.Linq" #>
<#@ import namespace="System" #>
<#@ import namespace="System.Reflection" #>
<#@ output extension=".cs" #>
namespace YourNameSpace
{
public static class Relationships
{
<#
var types = typeof(ConsoleApplication9.RelationshipAttribute).Assembly
.GetTypes()
.Select(t => new { t.Name, Value = t.GetCustomAttribute(typeof(ConsoleApplication9.RelationshipAttribute)) })
.Where(t => t.Value != null)
.Select(t=> new { t.Name,Value= ((ConsoleApplication9.RelationshipAttribute)t.Value).Name })
.ToList();
foreach (var attr in types)
{ #>
public static class <#= attr.Name #>
{
public const string <#= attr.Value #> = "<#= attr.Value #>";
}
<# }
#>}
}
将生成以下.cs文件
namespace YourNameSpace
{
public static class Relationships
{
public static class Class1
{
public const string RelationShipA = "RelationShipA";
}
public static class Class2
{
public const string RelationShipB = "RelationShipB";
}
public static class Class3
{
public const string RelationShipC = "RelationShipC";
}
}
}
然后你可以像
一样使用它Relationship = new Relationship(Relationships.Class1.RelationShipA )
答案 3 :(得分:4)
我不确定我的问题是否正确。
C#6.0功能nameof(...)
不会做这件事吗?
即
new Relationship(nameof(RelationshipSalesOrder.Relationships.SalesOrder_Annotation));
答案 4 :(得分:0)
XrmToolBox中的Early Bound Generator将为您生成这些关系名称。
public static class Fields
{
public const string AccountId = "accountid";
public const string AccountRoleCode = "accountrolecode";
public const string Address1_AddressId = "address1_addressid";
// *** SNIP ***
public const string YomiLastName = "yomilastname";
public const string YomiMiddleName = "yomimiddlename";
public const string business_unit_contacts = "business_unit_contacts";
public const string contact_customer_accounts = "contact_customer_accounts";
public const string Referencingcontact_customer_contacts = "contact_customer_contacts";
public const string Referencingcontact_master_contact = "contact_master_contact";
public const string contact_owning_user = "contact_owning_user";
public const string lk_contact_createdonbehalfby = "lk_contact_createdonbehalfby";
public const string lk_contact_modifiedonbehalfby = "lk_contact_modifiedonbehalfby";
public const string lk_contactbase_createdby = "lk_contactbase_createdby";
public const string lk_contactbase_modifiedby = "lk_contactbase_modifiedby";
public const string system_user_contacts = "system_user_contacts";
}