gpt4 book ai didi

c# - 应该使用 ToEntity 而不是类型转换吗?

转载 作者:太空狗 更新时间:2023-10-29 22:21:28 25 4
gpt4 key购买 nike

Xrm Sdk defines一个ToEntity<T>方法。我一直用它从 CRM 获取我早期绑定(bind)的实体。今天我正在审查一些代码,看到实体刚刚被转换:

var contact = service.Retrieve("contact", id, new ColumnSet()) as Contact;

我什至不知道这是可能的。甚至还需要 ToEntity 调用吗?

最佳答案

顺便说一句,这不是特定的转换,它是一种转换,转换的行为与直接转换略有不同。

As

You can use the as operator to perform certain types of conversions between compatible reference types or nullable types...The as operator is like a cast operation. However, if the conversion isn't possible, as returns null instead of raising an exception.

我假设您的 Contact 是由 CrmSvcUtil 创建的类,例如public partial class Contact : Microsoft.Xrm.Sdk.Entityservice.RetrieveIOrganizationService.Retrieve其返回类型为 Entity

Contact 是基类 Entity 的派生类。您不能将基类转换为更具体的派生类(请参阅 Is it possible to assign a base class object to a derived class reference with an explicit typecast in C#? )。如果您尝试执行从 EntityContact 的强制转换,您会遇到异常,并且转换会返回空对象。

包含来自 CrmSvcUtil 的 GeneratedCode 的示例,但与 CRM 没有实际连接。

var entity = new Entity();

Console.WriteLine($"Type of local entity: {entity.GetType()}");

Console.WriteLine($"Local entity as Contact is null? {entity as Contact == null}");

输出:

Type of local entity: Microsoft.Xrm.Sdk.Entity
Local entity as Contact is null? True

鉴于 Retrieve 返回一个 Entity,它不能被转换为 Contact,你的代码行 ( var contact = service.Retrieve("contact", id, new ColumnSet()) as Contact;) 还能用吗?

嗯,这很神奇。显然,如果您在应用程序中包含来自 CrmSvcUtil 的 GeneratedCode,则 Retrieve 函数会返回特定的派生类,而不是通用的 Entity

包含来自 CrmSvcUtil 的生成代码的示例:

CrmServiceClient service = new CrmServiceClient(ConfigurationManager.ConnectionStrings["Crm"].ConnectionString);

Contact c = new Contact()
{
LastName = "Test"
};

Guid contactId = service.Create(c);

var response = service.Retrieve("contact", contactId, new ColumnSet());

Console.WriteLine($"Type of response from CRM: {response.GetType()}");

Console.WriteLine($"Response from CRM as contact is null? {response as Contact == null}");

输出:

Type of response from CRM: Contact
Response from CRM as contact is null? False

不包含生成代码的示例:

CrmServiceClient service = new CrmServiceClient(ConfigurationManager.ConnectionStrings["Crm"].ConnectionString);

Entity c = new Entity("contact");
c["lastname"] = "Test";

Guid contactId = service.Create(c);

var response = service.Retrieve("contact", contactId, new ColumnSet());

Console.WriteLine($"Type of response: {response.GetType()}");

输出:

Type of response: Microsoft.Xrm.Sdk.Entity

回到你的问题。如果你在你的项目中包含生成的代码,假设 Retrieve 返回一个 Contact 无论如何你可以做一个简单的转换(例如 (Contact)service .Retrieve(...)) 或转换 (as)。就 ToEntity 的作用而言,它实际上并没有进行强制转换或转换。它创建一个新对象并执行浅拷贝等一些事情。因此,如果满足您的需要,请使用它,但没有它您也可以逃脱。

反编译代码:

public T ToEntity<T>() where T : Entity
{
if (typeof(T) == typeof(Entity))
{
Entity entity = new Entity();
this.ShallowCopyTo(entity);
return entity as T;
}
if (string.IsNullOrWhiteSpace(this._logicalName))
{
throw new NotSupportedException("LogicalName must be set before calling ToEntity()");
}
string text = null;
object[] customAttributes = typeof(T).GetCustomAttributes(typeof(EntityLogicalNameAttribute), true);
if (customAttributes != null)
{
object[] array = customAttributes;
int num = 0;
if (num < array.Length)
{
EntityLogicalNameAttribute entityLogicalNameAttribute = (EntityLogicalNameAttribute)array[num];
text = entityLogicalNameAttribute.LogicalName;
}
}
if (string.IsNullOrWhiteSpace(text))
{
throw new NotSupportedException("Cannot convert to type that is does not have EntityLogicalNameAttribute");
}
if (this._logicalName != text)
{
throw new NotSupportedException(string.Format(CultureInfo.InvariantCulture, "Cannot convert entity {0} to {1}", new object[]
{
this._logicalName,
text
}));
}
T t = (T)((object)Activator.CreateInstance(typeof(T)));
this.ShallowCopyTo(t);
return t;
}

关于c# - 应该使用 ToEntity<T> 而不是类型转换吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44024272/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com